From 88e5bfc630baa9a0789dd28694319afd506eae09 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 5 Mar 2026 16:36:54 +0100 Subject: [PATCH 01/78] Add a basic http OpAMP client (#3635) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a basic http OpAMP client * Add some docs and hook it into the system Still not building content * Add default value of 30 seconds to heartbeat message interval * Fix docs build * More docs improvements * Fix spellcheck * Remove local workaround * Generate workflows and add to release script * Fix typos in opamp lint commands * Fix requirements for pylint * Update opamp/opentelemetry-opamp-client/pyproject.toml * Recreate requirements * Add missing opentelemetry-api dependency * Fix tox test commands Drop opentelemetry api fixed version from requirements * Fix tox * Add baseline of vcrpy 7.0.0 * Ignore pb2 module in pylintrc * Bump pylint to match the version in core * Silence pylint warnings * Don't trace opamp client own http requests * Permit to pass a custom transport to client And a custom session to RequestsTransport * Don't bump pylint after all * Fix pylint * Try to typecheck opamp client * Bump version after rebase * Fix typecheck in client * Please pyright in strict mode * No need for functions and methods to be private since _opamp module is already private * Add missing protobuf package installation for typecheck * Fix docs generation * Fix pyright exclusion rule for proto Missed .pyi exclusion * Feedback * Don't flush the queue at exit * Log transport send exceptions * Update example to not assume that the config is in json format * Fix typo in exception * Looks like it's implementers * Add timeout to stop to forward to threads join * Clarify doc * Fix typo in var name * Add support for mTLS * Add helpers for handling of ReportFullState ServerToAgent flag Introducing basic handling of the ReportsEffectiveConfig capability * Remove backup file * Rewrite opamp_proto_codegen.sh to use uv * Make the package releasable independently * Send full state at connection * Add 3.14 test run * Add changelog entry * Add missing ReportsEffectiveConfig capability in documentation * Start version from 0.1b0 and re-record e2e tests * Record tests against opentelemetry-go --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .github/workflows/core_contrib_test_0.yml | 60 + .github/workflows/lint_0.yml | 19 + .../package-prepare-patch-release.yml | 1 + .github/workflows/package-prepare-release.yml | 1 + .github/workflows/package-release.yml | 1 + .github/workflows/test_2.yml | 228 ++ .pylintrc | 4 +- RELEASING.md | 2 + docs-requirements.txt | 5 + docs/conf.py | 33 +- docs/index.rst | 8 + docs/opamp/client.rst | 7 + eachdist.ini | 5 + opamp-gen-requirements.txt | 5 + opamp/opentelemetry-opamp-client/CHANGELOG.md | 11 + opamp/opentelemetry-opamp-client/LICENSE | 201 ++ opamp/opentelemetry-opamp-client/README.rst | 24 + .../opentelemetry-opamp-client/pyproject.toml | 47 + .../src/opentelemetry/_opamp/__init__.py | 95 + .../src/opentelemetry/_opamp/agent.py | 270 +++ .../src/opentelemetry/_opamp/client.py | 197 ++ .../src/opentelemetry/_opamp/exceptions.py | 25 + .../src/opentelemetry/_opamp/messages.py | 189 ++ .../_opamp/proto/anyvalue_pb2.py | 33 + .../_opamp/proto/anyvalue_pb2.pyi | 135 ++ .../opentelemetry/_opamp/proto/opamp_pb2.py | 144 ++ .../opentelemetry/_opamp/proto/opamp_pb2.pyi | 1987 +++++++++++++++++ .../opentelemetry/_opamp/transport/base.py | 40 + .../_opamp/transport/exceptions.py | 17 + .../_opamp/transport/requests.py | 67 + .../src/opentelemetry/_opamp/version.py | 15 + .../test-requirements.in | 18 + .../test-requirements.latest.txt | 87 + .../test-requirements.lowest.txt | 83 + .../tests/opamp/README.md | 23 + ...config_status_heartbeat_disconnection.yaml | 136 ++ .../tests/opamp/conftest.py | 33 + .../tests/opamp/test_agent.py | 210 ++ .../tests/opamp/test_client.py | 446 ++++ .../tests/opamp/test_e2e.py | 117 + .../tests/opamp/transport/test_requests.py | 178 ++ pyproject.toml | 3 + scripts/build.sh | 2 +- scripts/opamp_proto_codegen.sh | 74 + tox.ini | 16 + 45 files changed, 5292 insertions(+), 10 deletions(-) create mode 100644 docs/opamp/client.rst create mode 100644 opamp-gen-requirements.txt create mode 100644 opamp/opentelemetry-opamp-client/CHANGELOG.md create mode 100644 opamp/opentelemetry-opamp-client/LICENSE create mode 100644 opamp/opentelemetry-opamp-client/README.rst create mode 100644 opamp/opentelemetry-opamp-client/pyproject.toml create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/client.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/exceptions.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/messages.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/anyvalue_pb2.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/anyvalue_pb2.pyi create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/opamp_pb2.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/opamp_pb2.pyi create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/base.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/exceptions.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/requests.py create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py create mode 100644 opamp/opentelemetry-opamp-client/test-requirements.in create mode 100644 opamp/opentelemetry-opamp-client/test-requirements.latest.txt create mode 100644 opamp/opentelemetry-opamp-client/test-requirements.lowest.txt create mode 100644 opamp/opentelemetry-opamp-client/tests/opamp/README.md create mode 100644 opamp/opentelemetry-opamp-client/tests/opamp/cassettes/test_connection_remote_config_status_heartbeat_disconnection.yaml create mode 100644 opamp/opentelemetry-opamp-client/tests/opamp/conftest.py create mode 100644 opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py create mode 100644 opamp/opentelemetry-opamp-client/tests/opamp/test_client.py create mode 100644 opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py create mode 100644 opamp/opentelemetry-opamp-client/tests/opamp/transport/test_requests.py create mode 100755 scripts/opamp_proto_codegen.sh diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index fa7f0d668bc..d6950358ad0 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -3112,3 +3112,63 @@ jobs: - name: Run tests run: tox -e py39-test-processor-baggage -- -ra + + py39-test-opamp-client-latest: + name: opamp-client-latest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opamp-client-latest -- -ra + + py39-test-opamp-client-lowest: + name: opamp-client-lowest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opamp-client-lowest -- -ra diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index cb7b726df90..f43075df89c 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -1361,3 +1361,22 @@ jobs: - name: Run tests run: tox -e lint-processor-baggage + + lint-opamp-client: + name: opamp-client + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e lint-opamp-client diff --git a/.github/workflows/package-prepare-patch-release.yml b/.github/workflows/package-prepare-patch-release.yml index b7061e03e27..917a579cfa4 100644 --- a/.github/workflows/package-prepare-patch-release.yml +++ b/.github/workflows/package-prepare-patch-release.yml @@ -5,6 +5,7 @@ on: package: type: choice options: + - opentelemetry-opamp-client - opentelemetry-propagator-aws-xray - opentelemetry-resource-detector-azure - opentelemetry-sdk-extension-aws diff --git a/.github/workflows/package-prepare-release.yml b/.github/workflows/package-prepare-release.yml index f0bee0a606f..56b80728757 100644 --- a/.github/workflows/package-prepare-release.yml +++ b/.github/workflows/package-prepare-release.yml @@ -5,6 +5,7 @@ on: package: type: choice options: + - opentelemetry-opamp-client - opentelemetry-propagator-aws-xray - opentelemetry-resource-detector-azure - opentelemetry-sdk-extension-aws diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml index 1340bf967c5..7eb4b09d03d 100644 --- a/.github/workflows/package-release.yml +++ b/.github/workflows/package-release.yml @@ -5,6 +5,7 @@ on: package: type: choice options: + - opentelemetry-opamp-client - opentelemetry-propagator-aws-xray - opentelemetry-resource-detector-azure - opentelemetry-sdk-extension-aws diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index bdc6cefdae5..afa723c45a2 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -3641,3 +3641,231 @@ jobs: - name: Run tests run: tox -e pypy3-test-processor-baggage -- -ra + + py39-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opamp-client-latest -- -ra + + py39-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opamp-client-lowest -- -ra + + py310-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opamp-client-latest -- -ra + + py310-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opamp-client-lowest -- -ra + + py311-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opamp-client-latest -- -ra + + py311-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opamp-client-lowest -- -ra + + py312-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opamp-client-latest -- -ra + + py312-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opamp-client-lowest -- -ra + + py313-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opamp-client-latest -- -ra + + py313-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opamp-client-lowest -- -ra + + py314-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opamp-client-latest -- -ra + + py314-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opamp-client-lowest -- -ra diff --git a/.pylintrc b/.pylintrc index e51f6f43bd8..33fcdc1983b 100644 --- a/.pylintrc +++ b/.pylintrc @@ -7,7 +7,7 @@ extension-pkg-whitelist=cassandra # Add list of files or directories to be excluded. They should be base names, not # paths. -ignore=CVS,gen,Dockerfile,docker-compose.yml,README.md,requirements.txt,docs,.venv,site-packages,.tox +ignore=CVS,gen,Dockerfile,docker-compose.yml,README.md,requirements.txt,docs,.venv,site-packages,.tox,proto # Add files or directories matching the regex patterns to be excluded. The # regex matches against base names, not paths. @@ -179,7 +179,7 @@ contextmanager-decorators=contextlib.contextmanager # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E1101 when accessed. Python regular # expressions are accepted. -generated-members=types_pb2.* +generated-members=types_pb2.*,anyvalue_pb2.*,opamp_pb2.* # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). diff --git a/RELEASING.md b/RELEASING.md index 95cb24b4ec1..6213a6e442a 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -18,6 +18,7 @@ > [!NOTE] > Per-package release is supported for the following packages only: +> - opentelemetry-opamp-client > - opentelemetry-propagator-aws-xray > - opentelemetry-resource-detector-azure > - opentelemetry-sdk-extension-aws @@ -87,6 +88,7 @@ The workflow will create a pull request that should be merged in order to procee > [!NOTE] > Per-package patch release is supported for the following packages only: +> - opentelemetry-opamp-client > - opentelemetry-propagator-aws-xray > - opentelemetry-resource-detector-azure > - opentelemetry-sdk-extension-aws diff --git a/docs-requirements.txt b/docs-requirements.txt index 9d5e42fe74a..4914e9f780f 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -51,6 +51,11 @@ starlette~=0.50 tornado>=5.1.1 tortoise-orm>=0.17.0 +# required by opamp +uuid_utils +protobuf>=5.0,< 7.0 + # indirect dependency pins markupsafe==2.0.1 itsdangerous==2.0.1 + diff --git a/docs/conf.py b/docs/conf.py index 0f42c92be7d..b4e57200fb9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,21 +28,21 @@ exp = "../exporter" exp_dirs = [ - os.path.abspath("/".join(["../exporter", f, "src"])) + os.path.abspath("/".join([exp, f, "src"])) for f in listdir(exp) if isdir(join(exp, f)) ] instr = "../instrumentation" instr_dirs = [ - os.path.abspath("/".join(["../instrumentation", f, "src"])) + os.path.abspath("/".join([instr, f, "src"])) for f in listdir(instr) if isdir(join(instr, f)) ] instr_genai = "../instrumentation-genai" instr_genai_dirs = [ - os.path.abspath("/".join(["../instrumentation-genai", f, "src"])) + os.path.abspath("/".join([instr_genai, f, "src"])) for f in listdir(instr_genai) if isdir(join(instr_genai, f)) ] @@ -56,23 +56,32 @@ sdk_ext = "../sdk-extension" sdk_ext_dirs = [ - os.path.abspath("/".join(["../sdk-extension", f, "src"])) + os.path.abspath("/".join([sdk_ext, f, "src"])) for f in listdir(sdk_ext) if isdir(join(sdk_ext, f)) ] resource = "../resource" resource_dirs = [ - os.path.abspath("/".join(["../resource", f, "src"])) + os.path.abspath("/".join([resource, f, "src"])) for f in listdir(resource) if isdir(join(resource, f)) ] + util = "../util" util_dirs = [ os.path.abspath("/".join([util, f, "src"])) for f in listdir(util) if isdir(join(util, f)) ] + +opamp = "../opamp" +opamp_dirs = [ + os.path.abspath("/".join([opamp, f, "src"])) + for f in listdir(opamp) + if isdir(join(opamp, f)) +] + sys.path[:0] = ( exp_dirs + instr_dirs @@ -81,6 +90,7 @@ + prop_dirs + resource_dirs + util_dirs + + opamp_dirs ) # -- Project information ----------------------------------------------------- @@ -124,7 +134,7 @@ "https://opentracing-python.readthedocs.io/en/latest/", None, ), - "aiohttp": ("https://aiohttp.readthedocs.io/en/stable/", None), + "aiohttp": ("https://docs.aiohttp.org/en/stable/", None), "wrapt": ("https://wrapt.readthedocs.io/en/latest/", None), "pymongo": ("https://pymongo.readthedocs.io/en/stable/", None), "opentelemetry": ( @@ -141,7 +151,16 @@ # Sphinx does not recognize generic type TypeVars # Container supposedly were fixed, but does not work # https://github.com/sphinx-doc/sphinx/pull/3744 -nitpick_ignore = [] +nitpick_ignore = [ + ( + "py:class", + "opamp_pb2.RemoteConfigStatus", + ), + ( + "py:class", + "opamp_pb2.EffectiveConfig", + ), +] cfg = ConfigParser() cfg.read("./nitpick-exceptions.ini") diff --git a/docs/index.rst b/docs/index.rst index 11c611685bd..1ac7f8179c6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -103,6 +103,14 @@ install resource/** +.. toctree:: + :maxdepth: 2 + :caption: OpAMP + :name: OpAMP + :glob: + + opamp/** + Indices and tables ------------------ diff --git a/docs/opamp/client.rst b/docs/opamp/client.rst new file mode 100644 index 00000000000..74ababd2db6 --- /dev/null +++ b/docs/opamp/client.rst @@ -0,0 +1,7 @@ +OpenTelemetry Python - OpAMP Client +=================================== + +.. automodule:: opentelemetry._opamp + :members: + :undoc-members: + :show-inheritance: diff --git a/eachdist.ini b/eachdist.ini index 14b4b00fca4..56c09f4361c 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -48,11 +48,16 @@ packages= [exclude_release] packages= + opentelemetry-opamp-client + opentelemetry-propagator-aws-xray opentelemetry-resource-detector-azure opentelemetry-sdk-extension-aws +<<<<<<< basic-http-opamp-client +======= opentelemetry-propagator-aws-xray opentelemetry-instrumentation-anthropic opentelemetry-instrumentation-claude-agent-sdk +>>>>>>> main opentelemetry-instrumentation-google-genai opentelemetry-instrumentation-vertexai opentelemetry-instrumentation-openai-v2 diff --git a/opamp-gen-requirements.txt b/opamp-gen-requirements.txt new file mode 100644 index 00000000000..3cd7e79a440 --- /dev/null +++ b/opamp-gen-requirements.txt @@ -0,0 +1,5 @@ +# Use caution when bumping this version to ensure compatibility with the currently supported protobuf version. +# Pinning this to the oldest grpcio version that supports protobuf 5 helps avoid RuntimeWarning messages +# from the generated protobuf code and ensures continued stability for newer grpcio versions. +grpcio-tools==1.63.2 +mypy-protobuf~=3.5.0 diff --git a/opamp/opentelemetry-opamp-client/CHANGELOG.md b/opamp/opentelemetry-opamp-client/CHANGELOG.md new file mode 100644 index 00000000000..6e312367062 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +- Initial implementation + ([#3635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3635)) diff --git a/opamp/opentelemetry-opamp-client/LICENSE b/opamp/opentelemetry-opamp-client/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/opamp/opentelemetry-opamp-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/opamp/opentelemetry-opamp-client/README.rst b/opamp/opentelemetry-opamp-client/README.rst new file mode 100644 index 00000000000..32aef2c5e39 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/README.rst @@ -0,0 +1,24 @@ +OpenTelemetry OpAMP Client +========================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-opamp-client.svg + :target: https://pypi.org/project/opentelemetry-opamp-client/ + +Installation +------------ + +:: + + pip install opentelemetry-opamp-client + + +This package provides an HTTP OpAMP client than can be used by OpenTelemetry distributions to provide remote config. + +References +---------- +* `OpenTelemetry OpAMP Client `_ +* `OpenTelemetry Project `_ +* `OpenTelemetry Python Examples `_ + diff --git a/opamp/opentelemetry-opamp-client/pyproject.toml b/opamp/opentelemetry-opamp-client/pyproject.toml new file mode 100644 index 00000000000..31f10501c5e --- /dev/null +++ b/opamp/opentelemetry-opamp-client/pyproject.toml @@ -0,0 +1,47 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-opamp-client" +dynamic = ["version"] +description = "OpenTelemetry OpAMP client" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.9" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] +dependencies = [ + "opentelemetry-api ~= 1.12", + "protobuf>=5.0, < 7.0", + "uuid-utils>=0.11.0, <1" +] + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opamp/opentelemetry-opamp-client" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" + +[tool.hatch.version] +path = "src/opentelemetry/_opamp/version.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py new file mode 100644 index 00000000000..571a9837a32 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py @@ -0,0 +1,95 @@ +# 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. + +""" +OpenTelemetry Python - OpAMP client +----------------------------------- + +This package provides a bunch of classes that can be used by OpenTelemetry distributions implementers +to implement remote config support via the `OpAMP protocol`_. + +The client implements the following capabilities: + +* ReportsStatus +* ReportsHeartbeat +* AcceptsRemoteConfig +* ReportsRemoteConfig +* ReportsEffectiveConfig + +These capabilities are enough to get a remote config from an OpAMP server, parse it, apply it and ack it. + +While the client supports pluggable transports, only an HTTP backends using the ``requests`` library is +implemented. Adding WebSocket support shouldn't be hard but it will require some rework in the OpAMPAgent +class. + +Since OpAMP APIs, config options or environment variables are not standardizes the distros are required +to provide code doing so. +OTel Python distros would need to provide their own message handler callback that implements the actual +change of whatever configuration their backends sends. + +Please note that the API is not finalized yet and so the name is called ``_opamp`` with the underscore. + +Usage +----- + +.. code-block:: python + + import os + + from opentelemetry._opamp.agent import OpAMPAgent + from opentelemetry._opamp.client import OpAMPClient + from opentelemetry._opamp.proto import opamp_pb2 as opamp_pb2 + from opentelemetry.sdk._configuration import _OTelSDKConfigurator + from opentelemetry.sdk.resources import OTELResourceDetector + + + def opamp_handler(agent: OpAMPAgent, client: OpAMPClient, message: opamp_pb2.ServerToAgent): + for config_filename, config in message.remote_config.config.config_map.items(): + print("do something") + + + class MyOpenTelemetryConfigurator(_OTelSDKConfigurator): + def _configure(self, **kwargs): + super()._configure(**kwargs) + + enable_opamp = False + endpoint = os.environ.get("OTEL_PYTHON_OPAMP_ENDPOINT") + if endpoint: + # this is not great but we don't have the calculated resource attributes around + # see https://github.com/open-telemetry/opentelemetry-python/pull/4646 for creating + # an entry point distros can implement + resource = OTELResourceDetector().detect() + agent_identifying_attributes = { + "service.name": resource.attributes.get("service.name"), + } + opamp_client = OpAMPClient( + endpoint=endpoint, + agent_identifying_attributes=agent_identifying_attributes, + ) + opamp_agent = OpAMPAgent( + interval=30, + message_handler=opamp_handler, + client=opamp_client, + ) + opamp_agent.start() + +API +--- +.. _OpAMP protocol: https://opentelemetry.io/docs/specs/opamp/ +""" + +from opentelemetry._opamp.agent import OpAMPAgent +from opentelemetry._opamp.client import OpAMPClient + +__all__ = ["OpAMPAgent", "OpAMPClient"] diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py new file mode 100644 index 00000000000..fe547c81c91 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py @@ -0,0 +1,270 @@ +# 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 __future__ import annotations + +import atexit +import logging +import queue +import random +import threading +from typing import Any, Callable + +from opentelemetry._opamp.client import OpAMPClient +from opentelemetry._opamp.proto import opamp_pb2 + +logger = logging.getLogger(__name__) + + +class _Job: + """ + Represents a single request job, with retry/backoff metadata. + """ + + def __init__( + self, + payload: Any, + max_retries: int = 1, + initial_backoff: float = 1.0, + callback: Callable[..., None] | None = None, + ): + self.payload = payload + self.attempt = 0 + self.max_retries = max_retries + self.initial_backoff = initial_backoff + # callback is called after OpAMP message handler is executed + self.callback = callback + + def should_retry(self) -> bool: + """Checks if we should retry again""" + return self.attempt <= self.max_retries + + def delay(self) -> float: + """Calculate the delay before next retry""" + assert self.attempt > 0 + return ( + self.initial_backoff + * (2 ** (self.attempt - 1)) + * random.uniform(0.8, 1.2) + ) + + +class OpAMPAgent: + """ + OpAMPAgent handles: + - periodic “heartbeat” calls enqueued at a fixed interval + - on-demand calls via send() + - exponential backoff retry on failures + - immediate cancellation of all jobs on shutdown + """ + + def __init__( + self, + *, + interval: float = 30, + message_handler: Callable[ + ["OpAMPAgent", OpAMPClient, opamp_pb2.ServerToAgent], None + ], + max_retries: int = 10, + heartbeat_max_retries: int = 1, + initial_backoff: float = 1.0, + client: OpAMPClient, + ): + """ + :param interval: seconds between heartbeat calls + :param message_handler: user provided function that takes the received ServerToAgent message + :param max_retries: how many times to retry a failed job for ad-hoc messages + :param heartbeat_max_retries: how many times to retry an heartbeat failed job + :param initial_backoff: base seconds for exponential backoff + :param client: an OpAMPClient instance + """ + self._interval = interval + self._handler = message_handler + self._max_retries = max_retries + self._heartbeat_max_retries = heartbeat_max_retries + self._initial_backoff = initial_backoff + + self._queue: queue.Queue[_Job] = queue.Queue() + self._stop = threading.Event() + + self._worker = threading.Thread( + name="OpAMPAgentWorker", target=self._run_worker, daemon=True + ) + self._scheduler = threading.Thread( + name="OpAMPAgentScheduler", target=self._run_scheduler, daemon=True + ) + # start scheduling only after connection with server has been established + self._schedule = False + + self._client = client + + def _enable_scheduler(self): + self._schedule = True + logger.debug("Connected with endpoint, enabling heartbeat") + + def start(self) -> None: + """ + Starts the scheduler and worker threads. + """ + self._stop.clear() + self._worker.start() + self._scheduler.start() + + atexit.register(self.stop) + + # enqueue the connection message so we can then enable heartbeat + payload = self._client.build_full_state_message() + self.send( + payload, + max_retries=self._max_retries, + callback=self._enable_scheduler, + ) + + def send( + self, + payload: Any, + max_retries: int | None = None, + callback: Callable[..., None] | None = None, + ) -> None: + """ + Enqueue an on-demand request. + """ + if not self._worker.is_alive(): + logger.warning( + "Called send() but worker thread is not alive. Worker threads is started with start()" + ) + + if max_retries is None: + max_retries = self._max_retries + job = _Job( + payload, + max_retries=max_retries, + initial_backoff=self._initial_backoff, + callback=callback, + ) + self._queue.put(job) + logger.debug("On-demand job enqueued: %r", payload) + + def _run_scheduler(self) -> None: + """ + After we made a connection, periodically enqueue “heartbeat” jobs until stop is signaled. + """ + while not self._stop.wait(self._interval): + if self._schedule: + payload = self._client.build_heartbeat_message() + job = _Job( + payload=payload, + max_retries=self._heartbeat_max_retries, + initial_backoff=self._initial_backoff, + ) + self._queue.put(job) + logger.debug("Periodic job enqueued") + + def _run_worker(self) -> None: + """ + Worker loop: pull jobs, attempt the message handler, retry on failure with backoff. + """ + # pylint: disable=broad-exception-caught + while not self._stop.is_set(): + try: + job: _Job = self._queue.get(timeout=1) + except queue.Empty: + continue + + message = None + while job.should_retry() and not self._stop.is_set(): + try: + message = self._client.send(job.payload) + logger.debug("Job succeeded: %r", job.payload) + break + except Exception as exc: + job.attempt += 1 + logger.warning( + "Job %r failed attempt %d/%d: %s", + job.payload, + job.attempt, + job.max_retries, + exc, + ) + + if not job.should_retry(): + logger.error( + "Job %r dropped after max retries", job.payload + ) + logger.exception(exc) + break + + # exponential backoff with +/- 20% jitter, interruptible by stop event + delay = job.delay() + logger.debug("Retrying in %.1fs", delay) + if self._stop.wait(delay): + # stop requested during backoff: abandon job + logger.debug( + "Stop signaled, abandoning job %r", job.payload + ) + break + + if message is not None: + # we can't do much if the handler fails other than logging + try: + self._handler(self, self._client, message) + logger.debug("Called Job message handler for: %r", message) + except Exception as exc: + logger.warning( + "Job %r handler failed with: %s", job.payload, exc + ) + + try: + if job.callback is not None: + job.callback() + except Exception as exc: + logging.warning("Callback for job failed: %s", exc) + finally: + self._queue.task_done() + + def stop(self, timeout: float | None = None) -> None: + """ + Signal server we are disconnecting and then threads to exit + + :param timeout: seconds to wait for each thread to join + """ + + # Before exiting send signal the server we are disconnecting to free our resources + # This is not required by the spec but is helpful in practice + logger.debug("Stopping OpAMPAgent: sending AgentDisconnect") + payload = self._client.build_agent_disconnect_message() + try: + self._client.send(payload) + except Exception: # pylint: disable=broad-exception-caught + logger.debug( + "Stopping OpAMPAgent: failed to send AgentDisconnect message" + ) + + logger.debug("Stopping OpAMPAgent: signaling threads") + # Signal threads to exit + self._stop.set() + # don't crash if the user calls stop() before start() or calls stop() multiple times + try: + self._worker.join(timeout=timeout) + except RuntimeError as exc: + logger.warning( + "Stopping OpAMPAgent: worker thread failed to join %s", exc + ) + try: + self._scheduler.join(timeout=timeout) + except RuntimeError as exc: + logger.warning( + "Stopping OpAMPAgent: scheduler thread failed to join %s", exc + ) + logger.debug("OpAMPAgent stopped") diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/client.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/client.py new file mode 100644 index 00000000000..234e15451eb --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/client.py @@ -0,0 +1,197 @@ +# 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 __future__ import annotations + +from logging import getLogger +from typing import Generator, Mapping + +from uuid_utils import uuid7 + +from opentelemetry._opamp import messages +from opentelemetry._opamp.proto import opamp_pb2 +from opentelemetry._opamp.transport.base import HttpTransport +from opentelemetry._opamp.transport.requests import RequestsTransport +from opentelemetry._opamp.version import __version__ +from opentelemetry.context import ( + _SUPPRESS_INSTRUMENTATION_KEY, + attach, + detach, + set_value, +) +from opentelemetry.util.types import AnyValue + +_logger = getLogger(__name__) + +_DEFAULT_OPAMP_TIMEOUT_MS = 1_000 + +_OPAMP_HTTP_HEADERS = { + "Content-Type": "application/x-protobuf", + "User-Agent": "OTel-OpAMP-Python/" + __version__, +} + +_HANDLED_CAPABILITIES = ( + opamp_pb2.AgentCapabilities.AgentCapabilities_ReportsStatus + | opamp_pb2.AgentCapabilities.AgentCapabilities_ReportsHeartbeat + | opamp_pb2.AgentCapabilities.AgentCapabilities_AcceptsRemoteConfig + | opamp_pb2.AgentCapabilities.AgentCapabilities_ReportsRemoteConfig + | opamp_pb2.AgentCapabilities.AgentCapabilities_ReportsEffectiveConfig +) + + +class OpAMPClient: + """ + OpAMPClient implement the helpers for building and sending messages that the agent will use. + """ + + def __init__( + self, + *, + endpoint: str, + headers: Mapping[str, str] | None = None, + timeout_millis: int = _DEFAULT_OPAMP_TIMEOUT_MS, + agent_identifying_attributes: Mapping[str, AnyValue], + agent_non_identifying_attributes: Mapping[str, AnyValue] | None = None, + transport: HttpTransport | None = None, + # this matches requests but can be mapped to other http libraries APIs + tls_certificate: str | bool = True, + tls_client_certificate: str | None = None, + tls_client_key: str | None = None, + ): + self._timeout_millis = timeout_millis + self._transport = ( + RequestsTransport() if transport is None else transport + ) + + self._endpoint = endpoint + headers = headers or {} + self._headers = {**_OPAMP_HTTP_HEADERS, **headers} + self._tls_certificate = tls_certificate + self._tls_client_certificate = tls_client_certificate + self._tls_client_key = tls_client_key + + self._agent_description = messages.build_agent_description( + identifying_attributes=agent_identifying_attributes, + non_identifying_attributes=agent_non_identifying_attributes, + ) + self._sequence_num: int = 0 + self._instance_uid: bytes = uuid7().bytes + self._remote_config_status: opamp_pb2.RemoteConfigStatus | None = None + self._effective_config: opamp_pb2.EffectiveConfig | None = None + + def build_agent_disconnect_message(self) -> bytes: + message = messages.build_agent_disconnect_message( + instance_uid=self._instance_uid, + sequence_num=self._sequence_num, + capabilities=_HANDLED_CAPABILITIES, + ) + data = messages.encode_message(message) + return data + + def build_heartbeat_message(self) -> bytes: + message = messages.build_heartbeat_message( + instance_uid=self._instance_uid, + sequence_num=self._sequence_num, + capabilities=_HANDLED_CAPABILITIES, + ) + data = messages.encode_message(message) + return data + + def update_effective_config( + self, effective_config: dict[str, dict[str, str]], content_type: str + ) -> opamp_pb2.EffectiveConfig: + self._effective_config = messages.build_effective_config_message( + config=effective_config, content_type=content_type + ) + return self._effective_config + + def update_remote_config_status( + self, + remote_config_hash: bytes, + status: opamp_pb2.RemoteConfigStatuses.ValueType, + error_message: str = "", + ) -> opamp_pb2.RemoteConfigStatus | None: + status_changed = ( + not self._remote_config_status + or self._remote_config_status.last_remote_config_hash + != remote_config_hash + or self._remote_config_status.status != status + or self._remote_config_status.error_message != error_message + ) + # if the status changed update we return the RemoteConfigStatus message so that we can send it to the server + if status_changed: + _logger.debug( + "Update remote config status changed for %s", + remote_config_hash, + ) + self._remote_config_status = ( + messages.build_remote_config_status_message( + last_remote_config_hash=remote_config_hash, + status=status, + error_message=error_message, + ) + ) + return self._remote_config_status + + return None + + def build_remote_config_status_response_message( + self, remote_config_status: opamp_pb2.RemoteConfigStatus + ) -> bytes: + message = messages.build_remote_config_status_response_message( + instance_uid=self._instance_uid, + sequence_num=self._sequence_num, + capabilities=_HANDLED_CAPABILITIES, + remote_config_status=remote_config_status, + ) + data = messages.encode_message(message) + return data + + def build_full_state_message(self) -> bytes: + message = messages.build_full_state_message( + instance_uid=self._instance_uid, + agent_description=self._agent_description, + remote_config_status=self._remote_config_status, + sequence_num=self._sequence_num, + effective_config=self._effective_config, + capabilities=_HANDLED_CAPABILITIES, + ) + data = messages.encode_message(message) + return data + + def send(self, data: bytes): + token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True)) + try: + response = self._transport.send( + url=self._endpoint, + headers=self._headers, + data=data, + timeout_millis=self._timeout_millis, + tls_certificate=self._tls_certificate, + tls_client_certificate=self._tls_client_certificate, + tls_client_key=self._tls_client_key, + ) + return response + finally: + self._sequence_num += 1 + detach(token) + + @staticmethod + def decode_remote_config( + remote_config: opamp_pb2.AgentRemoteConfig, + ) -> Generator[tuple[str, Mapping[str, AnyValue]]]: + for config_file, config in messages.decode_remote_config( + remote_config + ): + yield config_file, config diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/exceptions.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/exceptions.py new file mode 100644 index 00000000000..2f573b0a554 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/exceptions.py @@ -0,0 +1,25 @@ +# 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. + + +class OpAMPTimeoutError(Exception): + pass + + +class OpAMPRemoteConfigParseException(Exception): + pass + + +class OpAMPRemoteConfigDecodeException(Exception): + pass diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/messages.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/messages.py new file mode 100644 index 00000000000..04d4da0322f --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/messages.py @@ -0,0 +1,189 @@ +# 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. + +# pylint: disable=no-name-in-module + +from __future__ import annotations + +import json +from typing import Generator, Mapping + +from opentelemetry._opamp.exceptions import ( + OpAMPRemoteConfigDecodeException, + OpAMPRemoteConfigParseException, +) +from opentelemetry._opamp.proto import opamp_pb2 +from opentelemetry._opamp.proto.anyvalue_pb2 import ( + AnyValue as PB2AnyValue, +) +from opentelemetry._opamp.proto.anyvalue_pb2 import ( + KeyValue as PB2KeyValue, +) +from opentelemetry.util.types import AnyValue + + +def decode_message(data: bytes) -> opamp_pb2.ServerToAgent: + message = opamp_pb2.ServerToAgent() + message.ParseFromString(data) + return message + + +def _encode_value(value: AnyValue) -> PB2AnyValue: + if value is None: + return PB2AnyValue() + if isinstance(value, bool): + return PB2AnyValue(bool_value=value) + if isinstance(value, int): + return PB2AnyValue(int_value=value) + if isinstance(value, float): + return PB2AnyValue(double_value=value) + if isinstance(value, str): + return PB2AnyValue(string_value=value) + if isinstance(value, bytes): + return PB2AnyValue(bytes_value=value) + # TODO: handle sequence and mapping? + raise ValueError(f"Invalid type {type(value)} of value {value}") + + +def _encode_attributes(attributes: Mapping[str, AnyValue]): + return [ + PB2KeyValue(key=key, value=_encode_value(value)) + for key, value in attributes.items() + ] + + +def build_agent_description( + identifying_attributes: Mapping[str, AnyValue], + non_identifying_attributes: Mapping[str, AnyValue] | None = None, +) -> opamp_pb2.AgentDescription: + identifying_attrs = _encode_attributes(identifying_attributes) + non_identifying_attrs = ( + _encode_attributes(non_identifying_attributes) + if non_identifying_attributes + else None + ) + return opamp_pb2.AgentDescription( + identifying_attributes=identifying_attrs, + non_identifying_attributes=non_identifying_attrs, + ) + + +def build_heartbeat_message( + instance_uid: bytes, sequence_num: int, capabilities: int +) -> opamp_pb2.AgentToServer: + command = opamp_pb2.AgentToServer( + instance_uid=instance_uid, + sequence_num=sequence_num, + capabilities=capabilities, + ) + return command + + +def build_agent_disconnect_message( + instance_uid: bytes, sequence_num: int, capabilities: int +) -> opamp_pb2.AgentToServer: + command = opamp_pb2.AgentToServer( + instance_uid=instance_uid, + sequence_num=sequence_num, + agent_disconnect=opamp_pb2.AgentDisconnect(), + capabilities=capabilities, + ) + return command + + +def build_remote_config_status_message( + last_remote_config_hash: bytes, + status: opamp_pb2.RemoteConfigStatuses.ValueType, + error_message: str = "", +) -> opamp_pb2.RemoteConfigStatus: + return opamp_pb2.RemoteConfigStatus( + last_remote_config_hash=last_remote_config_hash, + status=status, + error_message=error_message, + ) + + +def build_remote_config_status_response_message( + instance_uid: bytes, + sequence_num: int, + capabilities: int, + remote_config_status: opamp_pb2.RemoteConfigStatus, +) -> opamp_pb2.AgentToServer: + command = opamp_pb2.AgentToServer( + instance_uid=instance_uid, + sequence_num=sequence_num, + remote_config_status=remote_config_status, + capabilities=capabilities, + ) + return command + + +def build_effective_config_message( + config: dict[str, dict[str, str]], content_type: str +): + agent_config_map = opamp_pb2.AgentConfigMap() + for filename, value in config.items(): + if content_type == "application/json": + body = json.dumps(value) + agent_config_map.config_map[filename].body = body.encode("utf-8") + agent_config_map.config_map[filename].content_type = content_type + return opamp_pb2.EffectiveConfig( + config_map=agent_config_map, + ) + + +def build_full_state_message( + instance_uid: bytes, + sequence_num: int, + agent_description: opamp_pb2.AgentDescription, + capabilities: int, + remote_config_status: opamp_pb2.RemoteConfigStatus | None, + effective_config: opamp_pb2.EffectiveConfig | None, +) -> opamp_pb2.AgentToServer: + command = opamp_pb2.AgentToServer( + instance_uid=instance_uid, + sequence_num=sequence_num, + agent_description=agent_description, + remote_config_status=remote_config_status, + effective_config=effective_config, + capabilities=capabilities, + ) + return command + + +def encode_message(data: opamp_pb2.AgentToServer) -> bytes: + return data.SerializeToString() + + +def decode_remote_config( + remote_config: opamp_pb2.AgentRemoteConfig, +) -> Generator[tuple[str, Mapping[str, AnyValue]]]: + for ( + config_file_name, + config_file, + ) in remote_config.config.config_map.items(): + if config_file.content_type in ("application/json", "text/json"): + try: + body = config_file.body.decode() + config_data = json.loads(body) + except (UnicodeDecodeError, json.JSONDecodeError) as exc: + raise OpAMPRemoteConfigDecodeException( + f"Failed to decode {config_file_name} with content type {config_file.content_type}: {exc}" + ) + + yield config_file_name, config_data + else: + raise OpAMPRemoteConfigParseException( + f"Cannot parse {config_file_name} with content type {config_file.content_type}" + ) diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/anyvalue_pb2.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/anyvalue_pb2.py new file mode 100644 index 00000000000..7d1cd9b5b67 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/anyvalue_pb2.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: anyvalue.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0e\x61nyvalue.proto\x12\x0bopamp.proto\"\xe8\x01\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\x17.opamp.proto.ArrayValueH\x00\x12\x31\n\x0ckvlist_value\x18\x06 \x01(\x0b\x32\x19.opamp.proto.KeyValueListH\x00\x12\x15\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00\x42\x07\n\x05value\"3\n\nArrayValue\x12%\n\x06values\x18\x01 \x03(\x0b\x32\x15.opamp.proto.AnyValue\"5\n\x0cKeyValueList\x12%\n\x06values\x18\x01 \x03(\x0b\x32\x15.opamp.proto.KeyValue\"=\n\x08KeyValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.opamp.proto.AnyValueB.Z,github.com/open-telemetry/opamp-go/protobufsb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'anyvalue_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'Z,github.com/open-telemetry/opamp-go/protobufs' + _globals['_ANYVALUE']._serialized_start=32 + _globals['_ANYVALUE']._serialized_end=264 + _globals['_ARRAYVALUE']._serialized_start=266 + _globals['_ARRAYVALUE']._serialized_end=317 + _globals['_KEYVALUELIST']._serialized_start=319 + _globals['_KEYVALUELIST']._serialized_end=372 + _globals['_KEYVALUE']._serialized_start=374 + _globals['_KEYVALUE']._serialized_end=435 +# @@protoc_insertion_point(module_scope) diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/anyvalue_pb2.pyi b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/anyvalue_pb2.pyi new file mode 100644 index 00000000000..5036b8eb5a1 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/anyvalue_pb2.pyi @@ -0,0 +1,135 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +This file is copied and modified from https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/common/v1/common.proto +Modifications: + - Removal of unneeded InstrumentationLibrary and StringKeyValue messages. + - Change of go_package to reference a package in this repo. + - Removal of gogoproto usage. +""" +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): + """AnyValue is used to represent 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: 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 + 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 = ..., + ) -> 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", "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", "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"] | 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). + """ + 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): + """KeyValue is 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: builtins.str + @property + def value(self) -> global___AnyValue: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___AnyValue | None = ..., + ) -> 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", "value", b"value"]) -> None: ... + +global___KeyValue = KeyValue diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/opamp_pb2.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/opamp_pb2.py new file mode 100644 index 00000000000..00a62682d60 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/opamp_pb2.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opamp.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from . import anyvalue_pb2 as anyvalue__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bopamp.proto\x12\x0bopamp.proto\x1a\x0e\x61nyvalue.proto\"\xae\x05\n\rAgentToServer\x12\x14\n\x0cinstance_uid\x18\x01 \x01(\x0c\x12\x14\n\x0csequence_num\x18\x02 \x01(\x04\x12\x38\n\x11\x61gent_description\x18\x03 \x01(\x0b\x32\x1d.opamp.proto.AgentDescription\x12\x14\n\x0c\x63\x61pabilities\x18\x04 \x01(\x04\x12,\n\x06health\x18\x05 \x01(\x0b\x32\x1c.opamp.proto.ComponentHealth\x12\x36\n\x10\x65\x66\x66\x65\x63tive_config\x18\x06 \x01(\x0b\x32\x1c.opamp.proto.EffectiveConfig\x12=\n\x14remote_config_status\x18\x07 \x01(\x0b\x32\x1f.opamp.proto.RemoteConfigStatus\x12\x36\n\x10package_statuses\x18\x08 \x01(\x0b\x32\x1c.opamp.proto.PackageStatuses\x12\x36\n\x10\x61gent_disconnect\x18\t \x01(\x0b\x32\x1c.opamp.proto.AgentDisconnect\x12\r\n\x05\x66lags\x18\n \x01(\x04\x12K\n\x1b\x63onnection_settings_request\x18\x0b \x01(\x0b\x32&.opamp.proto.ConnectionSettingsRequest\x12<\n\x13\x63ustom_capabilities\x18\x0c \x01(\x0b\x32\x1f.opamp.proto.CustomCapabilities\x12\x32\n\x0e\x63ustom_message\x18\r \x01(\x0b\x32\x1a.opamp.proto.CustomMessage\x12>\n\x14\x61vailable_components\x18\x0e \x01(\x0b\x32 .opamp.proto.AvailableComponents\"\x11\n\x0f\x41gentDisconnect\"W\n\x19\x43onnectionSettingsRequest\x12:\n\x05opamp\x18\x01 \x01(\x0b\x32+.opamp.proto.OpAMPConnectionSettingsRequest\"^\n\x1eOpAMPConnectionSettingsRequest\x12<\n\x13\x63\x65rtificate_request\x18\x01 \x01(\x0b\x32\x1f.opamp.proto.CertificateRequest\"!\n\x12\x43\x65rtificateRequest\x12\x0b\n\x03\x63sr\x18\x01 \x01(\x0c\"\xbb\x01\n\x13\x41vailableComponents\x12\x44\n\ncomponents\x18\x01 \x03(\x0b\x32\x30.opamp.proto.AvailableComponents.ComponentsEntry\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\x1aP\n\x0f\x43omponentsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x1d.opamp.proto.ComponentDetails:\x02\x38\x01\"\xe1\x01\n\x10\x43omponentDetails\x12\'\n\x08metadata\x18\x01 \x03(\x0b\x32\x15.opamp.proto.KeyValue\x12M\n\x11sub_component_map\x18\x02 \x03(\x0b\x32\x32.opamp.proto.ComponentDetails.SubComponentMapEntry\x1aU\n\x14SubComponentMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x1d.opamp.proto.ComponentDetails:\x02\x38\x01\"\xa1\x04\n\rServerToAgent\x12\x14\n\x0cinstance_uid\x18\x01 \x01(\x0c\x12\x38\n\x0e\x65rror_response\x18\x02 \x01(\x0b\x32 .opamp.proto.ServerErrorResponse\x12\x35\n\rremote_config\x18\x03 \x01(\x0b\x32\x1e.opamp.proto.AgentRemoteConfig\x12\x42\n\x13\x63onnection_settings\x18\x04 \x01(\x0b\x32%.opamp.proto.ConnectionSettingsOffers\x12:\n\x12packages_available\x18\x05 \x01(\x0b\x32\x1e.opamp.proto.PackagesAvailable\x12\r\n\x05\x66lags\x18\x06 \x01(\x04\x12\x14\n\x0c\x63\x61pabilities\x18\x07 \x01(\x04\x12>\n\x14\x61gent_identification\x18\x08 \x01(\x0b\x32 .opamp.proto.AgentIdentification\x12\x32\n\x07\x63ommand\x18\t \x01(\x0b\x32!.opamp.proto.ServerToAgentCommand\x12<\n\x13\x63ustom_capabilities\x18\n \x01(\x0b\x32\x1f.opamp.proto.CustomCapabilities\x12\x32\n\x0e\x63ustom_message\x18\x0b \x01(\x0b\x32\x1a.opamp.proto.CustomMessage\"\xb4\x01\n\x17OpAMPConnectionSettings\x12\x1c\n\x14\x64\x65stination_endpoint\x18\x01 \x01(\t\x12%\n\x07headers\x18\x02 \x01(\x0b\x32\x14.opamp.proto.Headers\x12\x30\n\x0b\x63\x65rtificate\x18\x03 \x01(\x0b\x32\x1b.opamp.proto.TLSCertificate\x12\"\n\x1aheartbeat_interval_seconds\x18\x04 \x01(\x04\"\x94\x01\n\x1bTelemetryConnectionSettings\x12\x1c\n\x14\x64\x65stination_endpoint\x18\x01 \x01(\t\x12%\n\x07headers\x18\x02 \x01(\x0b\x32\x14.opamp.proto.Headers\x12\x30\n\x0b\x63\x65rtificate\x18\x03 \x01(\x0b\x32\x1b.opamp.proto.TLSCertificate\"\x97\x02\n\x17OtherConnectionSettings\x12\x1c\n\x14\x64\x65stination_endpoint\x18\x01 \x01(\t\x12%\n\x07headers\x18\x02 \x01(\x0b\x32\x14.opamp.proto.Headers\x12\x30\n\x0b\x63\x65rtificate\x18\x03 \x01(\x0b\x32\x1b.opamp.proto.TLSCertificate\x12O\n\x0eother_settings\x18\x04 \x03(\x0b\x32\x37.opamp.proto.OtherConnectionSettings.OtherSettingsEntry\x1a\x34\n\x12OtherSettingsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"/\n\x07Headers\x12$\n\x07headers\x18\x01 \x03(\x0b\x32\x13.opamp.proto.Header\"$\n\x06Header\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"D\n\x0eTLSCertificate\x12\x0c\n\x04\x63\x65rt\x18\x01 \x01(\x0c\x12\x13\n\x0bprivate_key\x18\x02 \x01(\x0c\x12\x0f\n\x07\x63\x61_cert\x18\x03 \x01(\x0c\"\xcd\x03\n\x18\x43onnectionSettingsOffers\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\x33\n\x05opamp\x18\x02 \x01(\x0b\x32$.opamp.proto.OpAMPConnectionSettings\x12=\n\x0bown_metrics\x18\x03 \x01(\x0b\x32(.opamp.proto.TelemetryConnectionSettings\x12<\n\nown_traces\x18\x04 \x01(\x0b\x32(.opamp.proto.TelemetryConnectionSettings\x12:\n\x08own_logs\x18\x05 \x01(\x0b\x32(.opamp.proto.TelemetryConnectionSettings\x12V\n\x11other_connections\x18\x06 \x03(\x0b\x32;.opamp.proto.ConnectionSettingsOffers.OtherConnectionsEntry\x1a]\n\x15OtherConnectionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x33\n\x05value\x18\x02 \x01(\x0b\x32$.opamp.proto.OtherConnectionSettings:\x02\x38\x01\"\xbe\x01\n\x11PackagesAvailable\x12>\n\x08packages\x18\x01 \x03(\x0b\x32,.opamp.proto.PackagesAvailable.PackagesEntry\x12\x19\n\x11\x61ll_packages_hash\x18\x02 \x01(\x0c\x1aN\n\rPackagesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x1d.opamp.proto.PackageAvailable:\x02\x38\x01\"\x86\x01\n\x10PackageAvailable\x12&\n\x04type\x18\x01 \x01(\x0e\x32\x18.opamp.proto.PackageType\x12\x0f\n\x07version\x18\x02 \x01(\t\x12+\n\x04\x66ile\x18\x03 \x01(\x0b\x32\x1d.opamp.proto.DownloadableFile\x12\x0c\n\x04hash\x18\x04 \x01(\x0c\"x\n\x10\x44ownloadableFile\x12\x14\n\x0c\x64ownload_url\x18\x01 \x01(\t\x12\x14\n\x0c\x63ontent_hash\x18\x02 \x01(\x0c\x12\x11\n\tsignature\x18\x03 \x01(\x0c\x12%\n\x07headers\x18\x04 \x01(\x0b\x32\x14.opamp.proto.Headers\"\x99\x01\n\x13ServerErrorResponse\x12\x32\n\x04type\x18\x01 \x01(\x0e\x32$.opamp.proto.ServerErrorResponseType\x12\x15\n\rerror_message\x18\x02 \x01(\t\x12,\n\nretry_info\x18\x03 \x01(\x0b\x32\x16.opamp.proto.RetryInfoH\x00\x42\t\n\x07\x44\x65tails\",\n\tRetryInfo\x12\x1f\n\x17retry_after_nanoseconds\x18\x01 \x01(\x04\">\n\x14ServerToAgentCommand\x12&\n\x04type\x18\x01 \x01(\x0e\x32\x18.opamp.proto.CommandType\"\x84\x01\n\x10\x41gentDescription\x12\x35\n\x16identifying_attributes\x18\x01 \x03(\x0b\x32\x15.opamp.proto.KeyValue\x12\x39\n\x1anon_identifying_attributes\x18\x02 \x03(\x0b\x32\x15.opamp.proto.KeyValue\"\xb0\x02\n\x0f\x43omponentHealth\x12\x0f\n\x07healthy\x18\x01 \x01(\x08\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x12\n\nlast_error\x18\x03 \x01(\t\x12\x0e\n\x06status\x18\x04 \x01(\t\x12\x1d\n\x15status_time_unix_nano\x18\x05 \x01(\x06\x12R\n\x14\x63omponent_health_map\x18\x06 \x03(\x0b\x32\x34.opamp.proto.ComponentHealth.ComponentHealthMapEntry\x1aW\n\x17\x43omponentHealthMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12+\n\x05value\x18\x02 \x01(\x0b\x32\x1c.opamp.proto.ComponentHealth:\x02\x38\x01\"B\n\x0f\x45\x66\x66\x65\x63tiveConfig\x12/\n\nconfig_map\x18\x01 \x01(\x0b\x32\x1b.opamp.proto.AgentConfigMap\"\x7f\n\x12RemoteConfigStatus\x12\x1f\n\x17last_remote_config_hash\x18\x01 \x01(\x0c\x12\x31\n\x06status\x18\x02 \x01(\x0e\x32!.opamp.proto.RemoteConfigStatuses\x12\x15\n\rerror_message\x18\x03 \x01(\t\"\xde\x01\n\x0fPackageStatuses\x12<\n\x08packages\x18\x01 \x03(\x0b\x32*.opamp.proto.PackageStatuses.PackagesEntry\x12)\n!server_provided_all_packages_hash\x18\x02 \x01(\x0c\x12\x15\n\rerror_message\x18\x03 \x01(\t\x1aK\n\rPackagesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.opamp.proto.PackageStatus:\x02\x38\x01\"\x93\x02\n\rPackageStatus\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x19\n\x11\x61gent_has_version\x18\x02 \x01(\t\x12\x16\n\x0e\x61gent_has_hash\x18\x03 \x01(\x0c\x12\x1e\n\x16server_offered_version\x18\x04 \x01(\t\x12\x1b\n\x13server_offered_hash\x18\x05 \x01(\x0c\x12.\n\x06status\x18\x06 \x01(\x0e\x32\x1e.opamp.proto.PackageStatusEnum\x12\x15\n\rerror_message\x18\x07 \x01(\t\x12=\n\x10\x64ownload_details\x18\x08 \x01(\x0b\x32#.opamp.proto.PackageDownloadDetails\"U\n\x16PackageDownloadDetails\x12\x18\n\x10\x64ownload_percent\x18\x01 \x01(\x01\x12!\n\x19\x64ownload_bytes_per_second\x18\x02 \x01(\x01\"/\n\x13\x41gentIdentification\x12\x18\n\x10new_instance_uid\x18\x01 \x01(\x0c\"U\n\x11\x41gentRemoteConfig\x12+\n\x06\x63onfig\x18\x01 \x01(\x0b\x32\x1b.opamp.proto.AgentConfigMap\x12\x13\n\x0b\x63onfig_hash\x18\x02 \x01(\x0c\"\xa0\x01\n\x0e\x41gentConfigMap\x12>\n\nconfig_map\x18\x01 \x03(\x0b\x32*.opamp.proto.AgentConfigMap.ConfigMapEntry\x1aN\n\x0e\x43onfigMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12+\n\x05value\x18\x02 \x01(\x0b\x32\x1c.opamp.proto.AgentConfigFile:\x02\x38\x01\"5\n\x0f\x41gentConfigFile\x12\x0c\n\x04\x62ody\x18\x01 \x01(\x0c\x12\x14\n\x0c\x63ontent_type\x18\x02 \x01(\t\"*\n\x12\x43ustomCapabilities\x12\x14\n\x0c\x63\x61pabilities\x18\x01 \x03(\t\"?\n\rCustomMessage\x12\x12\n\ncapability\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c*c\n\x12\x41gentToServerFlags\x12\"\n\x1e\x41gentToServerFlags_Unspecified\x10\x00\x12)\n%AgentToServerFlags_RequestInstanceUid\x10\x01*\x92\x01\n\x12ServerToAgentFlags\x12\"\n\x1eServerToAgentFlags_Unspecified\x10\x00\x12&\n\"ServerToAgentFlags_ReportFullState\x10\x01\x12\x30\n,ServerToAgentFlags_ReportAvailableComponents\x10\x02*\xf7\x02\n\x12ServerCapabilities\x12\"\n\x1eServerCapabilities_Unspecified\x10\x00\x12$\n ServerCapabilities_AcceptsStatus\x10\x01\x12)\n%ServerCapabilities_OffersRemoteConfig\x10\x02\x12-\n)ServerCapabilities_AcceptsEffectiveConfig\x10\x04\x12%\n!ServerCapabilities_OffersPackages\x10\x08\x12,\n(ServerCapabilities_AcceptsPackagesStatus\x10\x10\x12/\n+ServerCapabilities_OffersConnectionSettings\x10 \x12\x37\n3ServerCapabilities_AcceptsConnectionSettingsRequest\x10@*>\n\x0bPackageType\x12\x18\n\x14PackageType_TopLevel\x10\x00\x12\x15\n\x11PackageType_Addon\x10\x01*\x8f\x01\n\x17ServerErrorResponseType\x12#\n\x1fServerErrorResponseType_Unknown\x10\x00\x12&\n\"ServerErrorResponseType_BadRequest\x10\x01\x12\'\n#ServerErrorResponseType_Unavailable\x10\x02*&\n\x0b\x43ommandType\x12\x17\n\x13\x43ommandType_Restart\x10\x00*\xcc\x05\n\x11\x41gentCapabilities\x12!\n\x1d\x41gentCapabilities_Unspecified\x10\x00\x12#\n\x1f\x41gentCapabilities_ReportsStatus\x10\x01\x12)\n%AgentCapabilities_AcceptsRemoteConfig\x10\x02\x12,\n(AgentCapabilities_ReportsEffectiveConfig\x10\x04\x12%\n!AgentCapabilities_AcceptsPackages\x10\x08\x12,\n(AgentCapabilities_ReportsPackageStatuses\x10\x10\x12&\n\"AgentCapabilities_ReportsOwnTraces\x10 \x12\'\n#AgentCapabilities_ReportsOwnMetrics\x10@\x12%\n AgentCapabilities_ReportsOwnLogs\x10\x80\x01\x12\x35\n0AgentCapabilities_AcceptsOpAMPConnectionSettings\x10\x80\x02\x12\x35\n0AgentCapabilities_AcceptsOtherConnectionSettings\x10\x80\x04\x12,\n\'AgentCapabilities_AcceptsRestartCommand\x10\x80\x08\x12$\n\x1f\x41gentCapabilities_ReportsHealth\x10\x80\x10\x12*\n%AgentCapabilities_ReportsRemoteConfig\x10\x80 \x12\'\n\"AgentCapabilities_ReportsHeartbeat\x10\x80@\x12\x32\n,AgentCapabilities_ReportsAvailableComponents\x10\x80\x80\x01*\x9c\x01\n\x14RemoteConfigStatuses\x12\x1e\n\x1aRemoteConfigStatuses_UNSET\x10\x00\x12 \n\x1cRemoteConfigStatuses_APPLIED\x10\x01\x12!\n\x1dRemoteConfigStatuses_APPLYING\x10\x02\x12\x1f\n\x1bRemoteConfigStatuses_FAILED\x10\x03*\xc4\x01\n\x11PackageStatusEnum\x12\x1f\n\x1bPackageStatusEnum_Installed\x10\x00\x12$\n PackageStatusEnum_InstallPending\x10\x01\x12 \n\x1cPackageStatusEnum_Installing\x10\x02\x12#\n\x1fPackageStatusEnum_InstallFailed\x10\x03\x12!\n\x1dPackageStatusEnum_Downloading\x10\x04\x42.Z,github.com/open-telemetry/opamp-go/protobufsb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opamp_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'Z,github.com/open-telemetry/opamp-go/protobufs' + _globals['_AVAILABLECOMPONENTS_COMPONENTSENTRY']._loaded_options = None + _globals['_AVAILABLECOMPONENTS_COMPONENTSENTRY']._serialized_options = b'8\001' + _globals['_COMPONENTDETAILS_SUBCOMPONENTMAPENTRY']._loaded_options = None + _globals['_COMPONENTDETAILS_SUBCOMPONENTMAPENTRY']._serialized_options = b'8\001' + _globals['_OTHERCONNECTIONSETTINGS_OTHERSETTINGSENTRY']._loaded_options = None + _globals['_OTHERCONNECTIONSETTINGS_OTHERSETTINGSENTRY']._serialized_options = b'8\001' + _globals['_CONNECTIONSETTINGSOFFERS_OTHERCONNECTIONSENTRY']._loaded_options = None + _globals['_CONNECTIONSETTINGSOFFERS_OTHERCONNECTIONSENTRY']._serialized_options = b'8\001' + _globals['_PACKAGESAVAILABLE_PACKAGESENTRY']._loaded_options = None + _globals['_PACKAGESAVAILABLE_PACKAGESENTRY']._serialized_options = b'8\001' + _globals['_COMPONENTHEALTH_COMPONENTHEALTHMAPENTRY']._loaded_options = None + _globals['_COMPONENTHEALTH_COMPONENTHEALTHMAPENTRY']._serialized_options = b'8\001' + _globals['_PACKAGESTATUSES_PACKAGESENTRY']._loaded_options = None + _globals['_PACKAGESTATUSES_PACKAGESENTRY']._serialized_options = b'8\001' + _globals['_AGENTCONFIGMAP_CONFIGMAPENTRY']._loaded_options = None + _globals['_AGENTCONFIGMAP_CONFIGMAPENTRY']._serialized_options = b'8\001' + _globals['_AGENTTOSERVERFLAGS']._serialized_start=5585 + _globals['_AGENTTOSERVERFLAGS']._serialized_end=5684 + _globals['_SERVERTOAGENTFLAGS']._serialized_start=5687 + _globals['_SERVERTOAGENTFLAGS']._serialized_end=5833 + _globals['_SERVERCAPABILITIES']._serialized_start=5836 + _globals['_SERVERCAPABILITIES']._serialized_end=6211 + _globals['_PACKAGETYPE']._serialized_start=6213 + _globals['_PACKAGETYPE']._serialized_end=6275 + _globals['_SERVERERRORRESPONSETYPE']._serialized_start=6278 + _globals['_SERVERERRORRESPONSETYPE']._serialized_end=6421 + _globals['_COMMANDTYPE']._serialized_start=6423 + _globals['_COMMANDTYPE']._serialized_end=6461 + _globals['_AGENTCAPABILITIES']._serialized_start=6464 + _globals['_AGENTCAPABILITIES']._serialized_end=7180 + _globals['_REMOTECONFIGSTATUSES']._serialized_start=7183 + _globals['_REMOTECONFIGSTATUSES']._serialized_end=7339 + _globals['_PACKAGESTATUSENUM']._serialized_start=7342 + _globals['_PACKAGESTATUSENUM']._serialized_end=7538 + _globals['_AGENTTOSERVER']._serialized_start=45 + _globals['_AGENTTOSERVER']._serialized_end=731 + _globals['_AGENTDISCONNECT']._serialized_start=733 + _globals['_AGENTDISCONNECT']._serialized_end=750 + _globals['_CONNECTIONSETTINGSREQUEST']._serialized_start=752 + _globals['_CONNECTIONSETTINGSREQUEST']._serialized_end=839 + _globals['_OPAMPCONNECTIONSETTINGSREQUEST']._serialized_start=841 + _globals['_OPAMPCONNECTIONSETTINGSREQUEST']._serialized_end=935 + _globals['_CERTIFICATEREQUEST']._serialized_start=937 + _globals['_CERTIFICATEREQUEST']._serialized_end=970 + _globals['_AVAILABLECOMPONENTS']._serialized_start=973 + _globals['_AVAILABLECOMPONENTS']._serialized_end=1160 + _globals['_AVAILABLECOMPONENTS_COMPONENTSENTRY']._serialized_start=1080 + _globals['_AVAILABLECOMPONENTS_COMPONENTSENTRY']._serialized_end=1160 + _globals['_COMPONENTDETAILS']._serialized_start=1163 + _globals['_COMPONENTDETAILS']._serialized_end=1388 + _globals['_COMPONENTDETAILS_SUBCOMPONENTMAPENTRY']._serialized_start=1303 + _globals['_COMPONENTDETAILS_SUBCOMPONENTMAPENTRY']._serialized_end=1388 + _globals['_SERVERTOAGENT']._serialized_start=1391 + _globals['_SERVERTOAGENT']._serialized_end=1936 + _globals['_OPAMPCONNECTIONSETTINGS']._serialized_start=1939 + _globals['_OPAMPCONNECTIONSETTINGS']._serialized_end=2119 + _globals['_TELEMETRYCONNECTIONSETTINGS']._serialized_start=2122 + _globals['_TELEMETRYCONNECTIONSETTINGS']._serialized_end=2270 + _globals['_OTHERCONNECTIONSETTINGS']._serialized_start=2273 + _globals['_OTHERCONNECTIONSETTINGS']._serialized_end=2552 + _globals['_OTHERCONNECTIONSETTINGS_OTHERSETTINGSENTRY']._serialized_start=2500 + _globals['_OTHERCONNECTIONSETTINGS_OTHERSETTINGSENTRY']._serialized_end=2552 + _globals['_HEADERS']._serialized_start=2554 + _globals['_HEADERS']._serialized_end=2601 + _globals['_HEADER']._serialized_start=2603 + _globals['_HEADER']._serialized_end=2639 + _globals['_TLSCERTIFICATE']._serialized_start=2641 + _globals['_TLSCERTIFICATE']._serialized_end=2709 + _globals['_CONNECTIONSETTINGSOFFERS']._serialized_start=2712 + _globals['_CONNECTIONSETTINGSOFFERS']._serialized_end=3173 + _globals['_CONNECTIONSETTINGSOFFERS_OTHERCONNECTIONSENTRY']._serialized_start=3080 + _globals['_CONNECTIONSETTINGSOFFERS_OTHERCONNECTIONSENTRY']._serialized_end=3173 + _globals['_PACKAGESAVAILABLE']._serialized_start=3176 + _globals['_PACKAGESAVAILABLE']._serialized_end=3366 + _globals['_PACKAGESAVAILABLE_PACKAGESENTRY']._serialized_start=3288 + _globals['_PACKAGESAVAILABLE_PACKAGESENTRY']._serialized_end=3366 + _globals['_PACKAGEAVAILABLE']._serialized_start=3369 + _globals['_PACKAGEAVAILABLE']._serialized_end=3503 + _globals['_DOWNLOADABLEFILE']._serialized_start=3505 + _globals['_DOWNLOADABLEFILE']._serialized_end=3625 + _globals['_SERVERERRORRESPONSE']._serialized_start=3628 + _globals['_SERVERERRORRESPONSE']._serialized_end=3781 + _globals['_RETRYINFO']._serialized_start=3783 + _globals['_RETRYINFO']._serialized_end=3827 + _globals['_SERVERTOAGENTCOMMAND']._serialized_start=3829 + _globals['_SERVERTOAGENTCOMMAND']._serialized_end=3891 + _globals['_AGENTDESCRIPTION']._serialized_start=3894 + _globals['_AGENTDESCRIPTION']._serialized_end=4026 + _globals['_COMPONENTHEALTH']._serialized_start=4029 + _globals['_COMPONENTHEALTH']._serialized_end=4333 + _globals['_COMPONENTHEALTH_COMPONENTHEALTHMAPENTRY']._serialized_start=4246 + _globals['_COMPONENTHEALTH_COMPONENTHEALTHMAPENTRY']._serialized_end=4333 + _globals['_EFFECTIVECONFIG']._serialized_start=4335 + _globals['_EFFECTIVECONFIG']._serialized_end=4401 + _globals['_REMOTECONFIGSTATUS']._serialized_start=4403 + _globals['_REMOTECONFIGSTATUS']._serialized_end=4530 + _globals['_PACKAGESTATUSES']._serialized_start=4533 + _globals['_PACKAGESTATUSES']._serialized_end=4755 + _globals['_PACKAGESTATUSES_PACKAGESENTRY']._serialized_start=4680 + _globals['_PACKAGESTATUSES_PACKAGESENTRY']._serialized_end=4755 + _globals['_PACKAGESTATUS']._serialized_start=4758 + _globals['_PACKAGESTATUS']._serialized_end=5033 + _globals['_PACKAGEDOWNLOADDETAILS']._serialized_start=5035 + _globals['_PACKAGEDOWNLOADDETAILS']._serialized_end=5120 + _globals['_AGENTIDENTIFICATION']._serialized_start=5122 + _globals['_AGENTIDENTIFICATION']._serialized_end=5169 + _globals['_AGENTREMOTECONFIG']._serialized_start=5171 + _globals['_AGENTREMOTECONFIG']._serialized_end=5256 + _globals['_AGENTCONFIGMAP']._serialized_start=5259 + _globals['_AGENTCONFIGMAP']._serialized_end=5419 + _globals['_AGENTCONFIGMAP_CONFIGMAPENTRY']._serialized_start=5341 + _globals['_AGENTCONFIGMAP_CONFIGMAPENTRY']._serialized_end=5419 + _globals['_AGENTCONFIGFILE']._serialized_start=5421 + _globals['_AGENTCONFIGFILE']._serialized_end=5474 + _globals['_CUSTOMCAPABILITIES']._serialized_start=5476 + _globals['_CUSTOMCAPABILITIES']._serialized_end=5518 + _globals['_CUSTOMMESSAGE']._serialized_start=5520 + _globals['_CUSTOMMESSAGE']._serialized_end=5583 +# @@protoc_insertion_point(module_scope) diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/opamp_pb2.pyi b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/opamp_pb2.pyi new file mode 100644 index 00000000000..1f0ad4a2172 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto/opamp_pb2.pyi @@ -0,0 +1,1987 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +OpAMP: Open Agent Management Protocol (https://github.com/open-telemetry/opamp-spec)""" +import anyvalue_pb2 +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 sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _AgentToServerFlags: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _AgentToServerFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AgentToServerFlags.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + AgentToServerFlags_Unspecified: _AgentToServerFlags.ValueType # 0 + AgentToServerFlags_RequestInstanceUid: _AgentToServerFlags.ValueType # 1 + """AgentToServerFlags is a bit mask. Values below define individual bits. + + The Agent requests Server go generate a new instance_uid, which will + be sent back in ServerToAgent message + """ + +class AgentToServerFlags(_AgentToServerFlags, metaclass=_AgentToServerFlagsEnumTypeWrapper): ... + +AgentToServerFlags_Unspecified: AgentToServerFlags.ValueType # 0 +AgentToServerFlags_RequestInstanceUid: AgentToServerFlags.ValueType # 1 +"""AgentToServerFlags is a bit mask. Values below define individual bits. + +The Agent requests Server go generate a new instance_uid, which will +be sent back in ServerToAgent message +""" +global___AgentToServerFlags = AgentToServerFlags + +class _ServerToAgentFlags: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ServerToAgentFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ServerToAgentFlags.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ServerToAgentFlags_Unspecified: _ServerToAgentFlags.ValueType # 0 + ServerToAgentFlags_ReportFullState: _ServerToAgentFlags.ValueType # 1 + """Flags is a bit mask. Values below define individual bits. + + ReportFullState flag can be used by the Server if the Agent did not include the + particular bit of information in the last status report (which is an allowed + optimization) but the Server detects that it does not have it (e.g. was + restarted and lost state). The detection happens using + AgentToServer.sequence_num values. + The Server asks the Agent to report full status. + """ + ServerToAgentFlags_ReportAvailableComponents: _ServerToAgentFlags.ValueType # 2 + """ReportAvailableComponents flag can be used by the server if the Agent did + not include the full AvailableComponents message, but only the hash. + If this flag is specified, the agent will populate available_components.components + with a full description of the agent's components. + Status: [Development] + """ + +class ServerToAgentFlags(_ServerToAgentFlags, metaclass=_ServerToAgentFlagsEnumTypeWrapper): ... + +ServerToAgentFlags_Unspecified: ServerToAgentFlags.ValueType # 0 +ServerToAgentFlags_ReportFullState: ServerToAgentFlags.ValueType # 1 +"""Flags is a bit mask. Values below define individual bits. + +ReportFullState flag can be used by the Server if the Agent did not include the +particular bit of information in the last status report (which is an allowed +optimization) but the Server detects that it does not have it (e.g. was +restarted and lost state). The detection happens using +AgentToServer.sequence_num values. +The Server asks the Agent to report full status. +""" +ServerToAgentFlags_ReportAvailableComponents: ServerToAgentFlags.ValueType # 2 +"""ReportAvailableComponents flag can be used by the server if the Agent did +not include the full AvailableComponents message, but only the hash. +If this flag is specified, the agent will populate available_components.components +with a full description of the agent's components. +Status: [Development] +""" +global___ServerToAgentFlags = ServerToAgentFlags + +class _ServerCapabilities: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ServerCapabilitiesEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ServerCapabilities.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ServerCapabilities_Unspecified: _ServerCapabilities.ValueType # 0 + """The capabilities field is unspecified.""" + ServerCapabilities_AcceptsStatus: _ServerCapabilities.ValueType # 1 + """The Server can accept status reports. This bit MUST be set, since all Server + MUST be able to accept status reports. + """ + ServerCapabilities_OffersRemoteConfig: _ServerCapabilities.ValueType # 2 + """The Server can offer remote configuration to the Agent.""" + ServerCapabilities_AcceptsEffectiveConfig: _ServerCapabilities.ValueType # 4 + """The Server can accept EffectiveConfig in AgentToServer.""" + ServerCapabilities_OffersPackages: _ServerCapabilities.ValueType # 8 + """The Server can offer Packages. + Status: [Beta] + """ + ServerCapabilities_AcceptsPackagesStatus: _ServerCapabilities.ValueType # 16 + """The Server can accept Packages status. + Status: [Beta] + """ + ServerCapabilities_OffersConnectionSettings: _ServerCapabilities.ValueType # 32 + """The Server can offer connection settings. + Status: [Beta] + """ + ServerCapabilities_AcceptsConnectionSettingsRequest: _ServerCapabilities.ValueType # 64 + """The Server can accept ConnectionSettingsRequest and respond with an offer. + Status: [Development] + """ + +class ServerCapabilities(_ServerCapabilities, metaclass=_ServerCapabilitiesEnumTypeWrapper): ... + +ServerCapabilities_Unspecified: ServerCapabilities.ValueType # 0 +"""The capabilities field is unspecified.""" +ServerCapabilities_AcceptsStatus: ServerCapabilities.ValueType # 1 +"""The Server can accept status reports. This bit MUST be set, since all Server +MUST be able to accept status reports. +""" +ServerCapabilities_OffersRemoteConfig: ServerCapabilities.ValueType # 2 +"""The Server can offer remote configuration to the Agent.""" +ServerCapabilities_AcceptsEffectiveConfig: ServerCapabilities.ValueType # 4 +"""The Server can accept EffectiveConfig in AgentToServer.""" +ServerCapabilities_OffersPackages: ServerCapabilities.ValueType # 8 +"""The Server can offer Packages. +Status: [Beta] +""" +ServerCapabilities_AcceptsPackagesStatus: ServerCapabilities.ValueType # 16 +"""The Server can accept Packages status. +Status: [Beta] +""" +ServerCapabilities_OffersConnectionSettings: ServerCapabilities.ValueType # 32 +"""The Server can offer connection settings. +Status: [Beta] +""" +ServerCapabilities_AcceptsConnectionSettingsRequest: ServerCapabilities.ValueType # 64 +"""The Server can accept ConnectionSettingsRequest and respond with an offer. +Status: [Development] +""" +global___ServerCapabilities = ServerCapabilities + +class _PackageType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _PackageTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PackageType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + PackageType_TopLevel: _PackageType.ValueType # 0 + PackageType_Addon: _PackageType.ValueType # 1 + +class PackageType(_PackageType, metaclass=_PackageTypeEnumTypeWrapper): + """The type of the package, either an addon or a top-level package. + Status: [Beta] + """ + +PackageType_TopLevel: PackageType.ValueType # 0 +PackageType_Addon: PackageType.ValueType # 1 +global___PackageType = PackageType + +class _ServerErrorResponseType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ServerErrorResponseTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ServerErrorResponseType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ServerErrorResponseType_Unknown: _ServerErrorResponseType.ValueType # 0 + """Unknown error. Something went wrong, but it is not known what exactly. + The Agent SHOULD NOT retry the message. + The error_message field may contain a description of the problem. + """ + ServerErrorResponseType_BadRequest: _ServerErrorResponseType.ValueType # 1 + """The AgentToServer message was malformed. The Agent SHOULD NOT retry + the message. + """ + ServerErrorResponseType_Unavailable: _ServerErrorResponseType.ValueType # 2 + """The Server is overloaded and unable to process the request. The Agent + should retry the message later. retry_info field may be optionally + set with additional information about retrying. + """ + +class ServerErrorResponseType(_ServerErrorResponseType, metaclass=_ServerErrorResponseTypeEnumTypeWrapper): ... + +ServerErrorResponseType_Unknown: ServerErrorResponseType.ValueType # 0 +"""Unknown error. Something went wrong, but it is not known what exactly. +The Agent SHOULD NOT retry the message. +The error_message field may contain a description of the problem. +""" +ServerErrorResponseType_BadRequest: ServerErrorResponseType.ValueType # 1 +"""The AgentToServer message was malformed. The Agent SHOULD NOT retry +the message. +""" +ServerErrorResponseType_Unavailable: ServerErrorResponseType.ValueType # 2 +"""The Server is overloaded and unable to process the request. The Agent +should retry the message later. retry_info field may be optionally +set with additional information about retrying. +""" +global___ServerErrorResponseType = ServerErrorResponseType + +class _CommandType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _CommandTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CommandType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CommandType_Restart: _CommandType.ValueType # 0 + """The Agent should restart. This request will be ignored if the Agent does not + support restart. + """ + +class CommandType(_CommandType, metaclass=_CommandTypeEnumTypeWrapper): + """Status: [Beta]""" + +CommandType_Restart: CommandType.ValueType # 0 +"""The Agent should restart. This request will be ignored if the Agent does not +support restart. +""" +global___CommandType = CommandType + +class _AgentCapabilities: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _AgentCapabilitiesEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AgentCapabilities.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + AgentCapabilities_Unspecified: _AgentCapabilities.ValueType # 0 + """The capabilities field is unspecified.""" + AgentCapabilities_ReportsStatus: _AgentCapabilities.ValueType # 1 + """The Agent can report status. This bit MUST be set, since all Agents MUST + report status. + """ + AgentCapabilities_AcceptsRemoteConfig: _AgentCapabilities.ValueType # 2 + """The Agent can accept remote configuration from the Server.""" + AgentCapabilities_ReportsEffectiveConfig: _AgentCapabilities.ValueType # 4 + """The Agent will report EffectiveConfig in AgentToServer.""" + AgentCapabilities_AcceptsPackages: _AgentCapabilities.ValueType # 8 + """The Agent can accept package offers. + Status: [Beta] + """ + AgentCapabilities_ReportsPackageStatuses: _AgentCapabilities.ValueType # 16 + """The Agent can report package status. + Status: [Beta] + """ + AgentCapabilities_ReportsOwnTraces: _AgentCapabilities.ValueType # 32 + """The Agent can report own trace to the destination specified by + the Server via ConnectionSettingsOffers.own_traces field. + Status: [Beta] + """ + AgentCapabilities_ReportsOwnMetrics: _AgentCapabilities.ValueType # 64 + """The Agent can report own metrics to the destination specified by + the Server via ConnectionSettingsOffers.own_metrics field. + Status: [Beta] + """ + AgentCapabilities_ReportsOwnLogs: _AgentCapabilities.ValueType # 128 + """The Agent can report own logs to the destination specified by + the Server via ConnectionSettingsOffers.own_logs field. + Status: [Beta] + """ + AgentCapabilities_AcceptsOpAMPConnectionSettings: _AgentCapabilities.ValueType # 256 + """The can accept connections settings for OpAMP via + ConnectionSettingsOffers.opamp field. + Status: [Beta] + """ + AgentCapabilities_AcceptsOtherConnectionSettings: _AgentCapabilities.ValueType # 512 + """The can accept connections settings for other destinations via + ConnectionSettingsOffers.other_connections field. + Status: [Beta] + """ + AgentCapabilities_AcceptsRestartCommand: _AgentCapabilities.ValueType # 1024 + """The Agent can accept restart requests. + Status: [Beta] + """ + AgentCapabilities_ReportsHealth: _AgentCapabilities.ValueType # 2048 + """The Agent will report Health via AgentToServer.health field.""" + AgentCapabilities_ReportsRemoteConfig: _AgentCapabilities.ValueType # 4096 + """The Agent will report RemoteConfig status via AgentToServer.remote_config_status field.""" + AgentCapabilities_ReportsHeartbeat: _AgentCapabilities.ValueType # 8192 + """The Agent can report heartbeats. + This is specified by the ServerToAgent.OpAMPConnectionSettings.heartbeat_interval_seconds field. + If this capability is true, but the Server does not set a heartbeat_interval_seconds field, the + Agent should use its own configured interval, which by default will be 30s. The Server may not + know the configured interval and should not make assumptions about it. + Status: [Development] + """ + AgentCapabilities_ReportsAvailableComponents: _AgentCapabilities.ValueType # 16384 + """The agent will report AvailableComponents via the AgentToServer.available_components field. + Status: [Development] + Add new capabilities here, continuing with the least significant unused bit. + """ + +class AgentCapabilities(_AgentCapabilities, metaclass=_AgentCapabilitiesEnumTypeWrapper): ... + +AgentCapabilities_Unspecified: AgentCapabilities.ValueType # 0 +"""The capabilities field is unspecified.""" +AgentCapabilities_ReportsStatus: AgentCapabilities.ValueType # 1 +"""The Agent can report status. This bit MUST be set, since all Agents MUST +report status. +""" +AgentCapabilities_AcceptsRemoteConfig: AgentCapabilities.ValueType # 2 +"""The Agent can accept remote configuration from the Server.""" +AgentCapabilities_ReportsEffectiveConfig: AgentCapabilities.ValueType # 4 +"""The Agent will report EffectiveConfig in AgentToServer.""" +AgentCapabilities_AcceptsPackages: AgentCapabilities.ValueType # 8 +"""The Agent can accept package offers. +Status: [Beta] +""" +AgentCapabilities_ReportsPackageStatuses: AgentCapabilities.ValueType # 16 +"""The Agent can report package status. +Status: [Beta] +""" +AgentCapabilities_ReportsOwnTraces: AgentCapabilities.ValueType # 32 +"""The Agent can report own trace to the destination specified by +the Server via ConnectionSettingsOffers.own_traces field. +Status: [Beta] +""" +AgentCapabilities_ReportsOwnMetrics: AgentCapabilities.ValueType # 64 +"""The Agent can report own metrics to the destination specified by +the Server via ConnectionSettingsOffers.own_metrics field. +Status: [Beta] +""" +AgentCapabilities_ReportsOwnLogs: AgentCapabilities.ValueType # 128 +"""The Agent can report own logs to the destination specified by +the Server via ConnectionSettingsOffers.own_logs field. +Status: [Beta] +""" +AgentCapabilities_AcceptsOpAMPConnectionSettings: AgentCapabilities.ValueType # 256 +"""The can accept connections settings for OpAMP via +ConnectionSettingsOffers.opamp field. +Status: [Beta] +""" +AgentCapabilities_AcceptsOtherConnectionSettings: AgentCapabilities.ValueType # 512 +"""The can accept connections settings for other destinations via +ConnectionSettingsOffers.other_connections field. +Status: [Beta] +""" +AgentCapabilities_AcceptsRestartCommand: AgentCapabilities.ValueType # 1024 +"""The Agent can accept restart requests. +Status: [Beta] +""" +AgentCapabilities_ReportsHealth: AgentCapabilities.ValueType # 2048 +"""The Agent will report Health via AgentToServer.health field.""" +AgentCapabilities_ReportsRemoteConfig: AgentCapabilities.ValueType # 4096 +"""The Agent will report RemoteConfig status via AgentToServer.remote_config_status field.""" +AgentCapabilities_ReportsHeartbeat: AgentCapabilities.ValueType # 8192 +"""The Agent can report heartbeats. +This is specified by the ServerToAgent.OpAMPConnectionSettings.heartbeat_interval_seconds field. +If this capability is true, but the Server does not set a heartbeat_interval_seconds field, the +Agent should use its own configured interval, which by default will be 30s. The Server may not +know the configured interval and should not make assumptions about it. +Status: [Development] +""" +AgentCapabilities_ReportsAvailableComponents: AgentCapabilities.ValueType # 16384 +"""The agent will report AvailableComponents via the AgentToServer.available_components field. +Status: [Development] +Add new capabilities here, continuing with the least significant unused bit. +""" +global___AgentCapabilities = AgentCapabilities + +class _RemoteConfigStatuses: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _RemoteConfigStatusesEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_RemoteConfigStatuses.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + RemoteConfigStatuses_UNSET: _RemoteConfigStatuses.ValueType # 0 + """The value of status field is not set.""" + RemoteConfigStatuses_APPLIED: _RemoteConfigStatuses.ValueType # 1 + """Remote config was successfully applied by the Agent.""" + RemoteConfigStatuses_APPLYING: _RemoteConfigStatuses.ValueType # 2 + """Agent is currently applying the remote config that it received earlier.""" + RemoteConfigStatuses_FAILED: _RemoteConfigStatuses.ValueType # 3 + """Agent tried to apply the config received earlier, but it failed. + See error_message for more details. + """ + +class RemoteConfigStatuses(_RemoteConfigStatuses, metaclass=_RemoteConfigStatusesEnumTypeWrapper): ... + +RemoteConfigStatuses_UNSET: RemoteConfigStatuses.ValueType # 0 +"""The value of status field is not set.""" +RemoteConfigStatuses_APPLIED: RemoteConfigStatuses.ValueType # 1 +"""Remote config was successfully applied by the Agent.""" +RemoteConfigStatuses_APPLYING: RemoteConfigStatuses.ValueType # 2 +"""Agent is currently applying the remote config that it received earlier.""" +RemoteConfigStatuses_FAILED: RemoteConfigStatuses.ValueType # 3 +"""Agent tried to apply the config received earlier, but it failed. +See error_message for more details. +""" +global___RemoteConfigStatuses = RemoteConfigStatuses + +class _PackageStatusEnum: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _PackageStatusEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PackageStatusEnum.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + PackageStatusEnum_Installed: _PackageStatusEnum.ValueType # 0 + """Package is successfully installed by the Agent. + The error_message field MUST NOT be set. + """ + PackageStatusEnum_InstallPending: _PackageStatusEnum.ValueType # 1 + """Installation of this package has not yet started.""" + PackageStatusEnum_Installing: _PackageStatusEnum.ValueType # 2 + """Agent is currently installing the package. + server_offered_hash field MUST be set to indicate the version that the + Agent is installing. The error_message field MUST NOT be set. + """ + PackageStatusEnum_InstallFailed: _PackageStatusEnum.ValueType # 3 + """Agent tried to install the package but installation failed. + server_offered_hash field MUST be set to indicate the version that the Agent + tried to install. The error_message may also contain more details about + the failure. + """ + PackageStatusEnum_Downloading: _PackageStatusEnum.ValueType # 4 + """Agent is currently downloading the package. + server_offered_hash field MUST be set to indicate the version that the + Agent is installing. The error_message field MUST NOT be set. + Status: [Development] + """ + +class PackageStatusEnum(_PackageStatusEnum, metaclass=_PackageStatusEnumEnumTypeWrapper): + """The status of this package. + Status: [Beta] + """ + +PackageStatusEnum_Installed: PackageStatusEnum.ValueType # 0 +"""Package is successfully installed by the Agent. +The error_message field MUST NOT be set. +""" +PackageStatusEnum_InstallPending: PackageStatusEnum.ValueType # 1 +"""Installation of this package has not yet started.""" +PackageStatusEnum_Installing: PackageStatusEnum.ValueType # 2 +"""Agent is currently installing the package. +server_offered_hash field MUST be set to indicate the version that the +Agent is installing. The error_message field MUST NOT be set. +""" +PackageStatusEnum_InstallFailed: PackageStatusEnum.ValueType # 3 +"""Agent tried to install the package but installation failed. +server_offered_hash field MUST be set to indicate the version that the Agent +tried to install. The error_message may also contain more details about +the failure. +""" +PackageStatusEnum_Downloading: PackageStatusEnum.ValueType # 4 +"""Agent is currently downloading the package. +server_offered_hash field MUST be set to indicate the version that the +Agent is installing. The error_message field MUST NOT be set. +Status: [Development] +""" +global___PackageStatusEnum = PackageStatusEnum + +@typing_extensions.final +class AgentToServer(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTANCE_UID_FIELD_NUMBER: builtins.int + SEQUENCE_NUM_FIELD_NUMBER: builtins.int + AGENT_DESCRIPTION_FIELD_NUMBER: builtins.int + CAPABILITIES_FIELD_NUMBER: builtins.int + HEALTH_FIELD_NUMBER: builtins.int + EFFECTIVE_CONFIG_FIELD_NUMBER: builtins.int + REMOTE_CONFIG_STATUS_FIELD_NUMBER: builtins.int + PACKAGE_STATUSES_FIELD_NUMBER: builtins.int + AGENT_DISCONNECT_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + CONNECTION_SETTINGS_REQUEST_FIELD_NUMBER: builtins.int + CUSTOM_CAPABILITIES_FIELD_NUMBER: builtins.int + CUSTOM_MESSAGE_FIELD_NUMBER: builtins.int + AVAILABLE_COMPONENTS_FIELD_NUMBER: builtins.int + instance_uid: builtins.bytes + """Globally unique identifier of the running instance of the Agent. SHOULD remain + unchanged for the lifetime of the Agent process. + MUST be 16 bytes long and SHOULD be generated using the UUID v7 spec. + """ + sequence_num: builtins.int + """The sequence number is incremented by 1 for every AgentToServer sent + by the Agent. This allows the Server to detect that it missed a message when + it notices that the sequence_num is not exactly by 1 greater than the previously + received one. + """ + @property + def agent_description(self) -> global___AgentDescription: + """Data that describes the Agent, its type, where it runs, etc. + May be omitted if nothing changed since last AgentToServer message. + """ + capabilities: builtins.int + """Bitmask of flags defined by AgentCapabilities enum. + All bits that are not defined in AgentCapabilities enum MUST be set to 0 by + the Agent. This allows extending the protocol and the AgentCapabilities enum + in the future such that old Agents automatically report that they don't + support the new capability. + This field MUST be always set. + """ + @property + def health(self) -> global___ComponentHealth: + """The current health of the Agent and sub-components. The top-level ComponentHealth represents + the health of the Agent overall. May be omitted if nothing changed since last AgentToServer + message. + Status: [Beta] + """ + @property + def effective_config(self) -> global___EffectiveConfig: + """The current effective configuration of the Agent. The effective configuration is + the one that is currently used by the Agent. The effective configuration may be + different from the remote configuration received from the Server earlier, e.g. + because the Agent uses a local configuration instead (or in addition). + + This field SHOULD be unset if the effective config is unchanged since the last + AgentToServer message. + """ + @property + def remote_config_status(self) -> global___RemoteConfigStatus: + """The status of the remote config that was previously received from the Server. + This field SHOULD be unset if the remote config status is unchanged since the + last AgentToServer message. + """ + @property + def package_statuses(self) -> global___PackageStatuses: + """The list of the Agent packages, including package statuses. This field SHOULD be + unset if this information is unchanged since the last AgentToServer message for + this Agent was sent in the stream. + Status: [Beta] + """ + @property + def agent_disconnect(self) -> global___AgentDisconnect: + """AgentDisconnect MUST be set in the last AgentToServer message sent from the + Agent to the Server. + """ + flags: builtins.int + """Bit flags as defined by AgentToServerFlags bit masks.""" + @property + def connection_settings_request(self) -> global___ConnectionSettingsRequest: + """A request to create connection settings. This field is set for flows where + the Agent initiates the creation of connection settings. + Status: [Development] + """ + @property + def custom_capabilities(self) -> global___CustomCapabilities: + """A message indicating custom capabilities supported by the Agent. + Status: [Development] + """ + @property + def custom_message(self) -> global___CustomMessage: + """A custom message sent from an Agent to the Server. + Status: [Development] + """ + @property + def available_components(self) -> global___AvailableComponents: + """A message indicating the components that are available for configuration on the agent. + Status: [Development] + """ + def __init__( + self, + *, + instance_uid: builtins.bytes = ..., + sequence_num: builtins.int = ..., + agent_description: global___AgentDescription | None = ..., + capabilities: builtins.int = ..., + health: global___ComponentHealth | None = ..., + effective_config: global___EffectiveConfig | None = ..., + remote_config_status: global___RemoteConfigStatus | None = ..., + package_statuses: global___PackageStatuses | None = ..., + agent_disconnect: global___AgentDisconnect | None = ..., + flags: builtins.int = ..., + connection_settings_request: global___ConnectionSettingsRequest | None = ..., + custom_capabilities: global___CustomCapabilities | None = ..., + custom_message: global___CustomMessage | None = ..., + available_components: global___AvailableComponents | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["agent_description", b"agent_description", "agent_disconnect", b"agent_disconnect", "available_components", b"available_components", "connection_settings_request", b"connection_settings_request", "custom_capabilities", b"custom_capabilities", "custom_message", b"custom_message", "effective_config", b"effective_config", "health", b"health", "package_statuses", b"package_statuses", "remote_config_status", b"remote_config_status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["agent_description", b"agent_description", "agent_disconnect", b"agent_disconnect", "available_components", b"available_components", "capabilities", b"capabilities", "connection_settings_request", b"connection_settings_request", "custom_capabilities", b"custom_capabilities", "custom_message", b"custom_message", "effective_config", b"effective_config", "flags", b"flags", "health", b"health", "instance_uid", b"instance_uid", "package_statuses", b"package_statuses", "remote_config_status", b"remote_config_status", "sequence_num", b"sequence_num"]) -> None: ... + +global___AgentToServer = AgentToServer + +@typing_extensions.final +class AgentDisconnect(google.protobuf.message.Message): + """AgentDisconnect is the last message sent from the Agent to the Server. The Server + SHOULD forget the association of the Agent instance with the message stream. + + If the message stream is closed in the transport layer then the Server SHOULD + forget association of all Agent instances that were previously established for + this message stream using AgentConnect message, even if the corresponding + AgentDisconnect message were not explicitly received from the Agent. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +global___AgentDisconnect = AgentDisconnect + +@typing_extensions.final +class ConnectionSettingsRequest(google.protobuf.message.Message): + """ConnectionSettingsRequest is a request from the Agent to the Server to create + and respond with an offer of connection settings for the Agent. + Status: [Development] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + OPAMP_FIELD_NUMBER: builtins.int + @property + def opamp(self) -> global___OpAMPConnectionSettingsRequest: + """Request for OpAMP connection settings. If this field is unset + then the ConnectionSettingsRequest message is empty and is not actionable + for the Server. + """ + def __init__( + self, + *, + opamp: global___OpAMPConnectionSettingsRequest | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["opamp", b"opamp"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["opamp", b"opamp"]) -> None: ... + +global___ConnectionSettingsRequest = ConnectionSettingsRequest + +@typing_extensions.final +class OpAMPConnectionSettingsRequest(google.protobuf.message.Message): + """OpAMPConnectionSettingsRequest is a request for the Server to produce + a OpAMPConnectionSettings in its response. + Status: [Development] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CERTIFICATE_REQUEST_FIELD_NUMBER: builtins.int + @property + def certificate_request(self) -> global___CertificateRequest: + """A request to create a client certificate. This is used to initiate a + Client Signing Request (CSR) flow. + Required. + """ + def __init__( + self, + *, + certificate_request: global___CertificateRequest | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["certificate_request", b"certificate_request"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["certificate_request", b"certificate_request"]) -> None: ... + +global___OpAMPConnectionSettingsRequest = OpAMPConnectionSettingsRequest + +@typing_extensions.final +class CertificateRequest(google.protobuf.message.Message): + """Status: [Development]""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CSR_FIELD_NUMBER: builtins.int + csr: builtins.bytes + """PEM-encoded Client Certificate Signing Request (CSR), signed by client's private key. + The Server SHOULD validate the request and SHOULD respond with a + OpAMPConnectionSettings where the certificate.cert contains the issued + certificate. + """ + def __init__( + self, + *, + csr: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["csr", b"csr"]) -> None: ... + +global___CertificateRequest = CertificateRequest + +@typing_extensions.final +class AvailableComponents(google.protobuf.message.Message): + """AvailableComponents contains metadata relating to the components included + within the agent. + status: [Development] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class ComponentsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___ComponentDetails: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___ComponentDetails | None = ..., + ) -> 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", "value", b"value"]) -> None: ... + + COMPONENTS_FIELD_NUMBER: builtins.int + HASH_FIELD_NUMBER: builtins.int + @property + def components(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___ComponentDetails]: + """A map of a unique component ID to details about the component. + This may be omitted from the message if the server has not + explicitly requested it be sent by setting the ReportAvailableComponents + flag in the previous ServerToAgent message. + """ + hash: builtins.bytes + """Agent-calculated hash of the components. + This hash should be included in every AvailableComponents message. + """ + def __init__( + self, + *, + components: collections.abc.Mapping[builtins.str, global___ComponentDetails] | None = ..., + hash: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["components", b"components", "hash", b"hash"]) -> None: ... + +global___AvailableComponents = AvailableComponents + +@typing_extensions.final +class ComponentDetails(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class SubComponentMapEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___ComponentDetails: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___ComponentDetails | None = ..., + ) -> 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", "value", b"value"]) -> None: ... + + METADATA_FIELD_NUMBER: builtins.int + SUB_COMPONENT_MAP_FIELD_NUMBER: builtins.int + @property + def metadata(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[anyvalue_pb2.KeyValue]: + """Extra key/value pairs that may be used to describe the component. + The key/value pairs are according to semantic conventions, see: + https://opentelemetry.io/docs/specs/semconv/ + + For example, you may use the "code" semantic conventions to + report the location of the code for a specific component: + https://opentelemetry.io/docs/specs/semconv/attributes-registry/code/ + + Or you may use the "vcs" semantic conventions to report the + repository the component may be a part of: + https://opentelemetry.io/docs/specs/semconv/attributes-registry/vcs/ + """ + @property + def sub_component_map(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___ComponentDetails]: + """A map of component ID to sub components details. It can nest as deeply as needed to + describe the underlying system. + """ + def __init__( + self, + *, + metadata: collections.abc.Iterable[anyvalue_pb2.KeyValue] | None = ..., + sub_component_map: collections.abc.Mapping[builtins.str, global___ComponentDetails] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["metadata", b"metadata", "sub_component_map", b"sub_component_map"]) -> None: ... + +global___ComponentDetails = ComponentDetails + +@typing_extensions.final +class ServerToAgent(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INSTANCE_UID_FIELD_NUMBER: builtins.int + ERROR_RESPONSE_FIELD_NUMBER: builtins.int + REMOTE_CONFIG_FIELD_NUMBER: builtins.int + CONNECTION_SETTINGS_FIELD_NUMBER: builtins.int + PACKAGES_AVAILABLE_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + CAPABILITIES_FIELD_NUMBER: builtins.int + AGENT_IDENTIFICATION_FIELD_NUMBER: builtins.int + COMMAND_FIELD_NUMBER: builtins.int + CUSTOM_CAPABILITIES_FIELD_NUMBER: builtins.int + CUSTOM_MESSAGE_FIELD_NUMBER: builtins.int + instance_uid: builtins.bytes + """Agent instance uid. MUST match the instance_uid field in AgentToServer message. + Used for multiplexing messages from/to multiple agents using one message stream. + """ + @property + def error_response(self) -> global___ServerErrorResponse: + """error_response is set if the Server wants to indicate that something went wrong + during processing of an AgentToServer message. If error_response is set then + all other fields below must be unset and vice versa, if any of the fields below is + set then error_response must be unset. + """ + @property + def remote_config(self) -> global___AgentRemoteConfig: + """remote_config field is set when the Server has a remote config offer for the Agent.""" + @property + def connection_settings(self) -> global___ConnectionSettingsOffers: + """This field is set when the Server wants the Agent to change one or more + of its client connection settings (destination, headers, certificate, etc). + Status: [Beta] + """ + @property + def packages_available(self) -> global___PackagesAvailable: + """This field is set when the Server has packages to offer to the Agent. + Status: [Beta] + """ + flags: builtins.int + """Bit flags as defined by ServerToAgentFlags bit masks.""" + capabilities: builtins.int + """Bitmask of flags defined by ServerCapabilities enum. + All bits that are not defined in ServerCapabilities enum MUST be set to 0 + by the Server. This allows extending the protocol and the ServerCapabilities + enum in the future such that old Servers automatically report that they + don't support the new capability. + This field MUST be set in the first ServerToAgent sent by the Server and MAY + be omitted in subsequent ServerToAgent messages by setting it to + UnspecifiedServerCapability value. + """ + @property + def agent_identification(self) -> global___AgentIdentification: + """Properties related to identification of the Agent, which can be overridden + by the Server if needed. + """ + @property + def command(self) -> global___ServerToAgentCommand: + """Allows the Server to instruct the Agent to perform a command, e.g. RESTART. This field should not be specified + with fields other than instance_uid and capabilities. If specified, other fields will be ignored and the command + will be performed. + Status: [Beta] + """ + @property + def custom_capabilities(self) -> global___CustomCapabilities: + """A message indicating custom capabilities supported by the Server. + Status: [Development] + """ + @property + def custom_message(self) -> global___CustomMessage: + """A custom message sent from the Server to an Agent. + Status: [Development] + """ + def __init__( + self, + *, + instance_uid: builtins.bytes = ..., + error_response: global___ServerErrorResponse | None = ..., + remote_config: global___AgentRemoteConfig | None = ..., + connection_settings: global___ConnectionSettingsOffers | None = ..., + packages_available: global___PackagesAvailable | None = ..., + flags: builtins.int = ..., + capabilities: builtins.int = ..., + agent_identification: global___AgentIdentification | None = ..., + command: global___ServerToAgentCommand | None = ..., + custom_capabilities: global___CustomCapabilities | None = ..., + custom_message: global___CustomMessage | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["agent_identification", b"agent_identification", "command", b"command", "connection_settings", b"connection_settings", "custom_capabilities", b"custom_capabilities", "custom_message", b"custom_message", "error_response", b"error_response", "packages_available", b"packages_available", "remote_config", b"remote_config"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["agent_identification", b"agent_identification", "capabilities", b"capabilities", "command", b"command", "connection_settings", b"connection_settings", "custom_capabilities", b"custom_capabilities", "custom_message", b"custom_message", "error_response", b"error_response", "flags", b"flags", "instance_uid", b"instance_uid", "packages_available", b"packages_available", "remote_config", b"remote_config"]) -> None: ... + +global___ServerToAgent = ServerToAgent + +@typing_extensions.final +class OpAMPConnectionSettings(google.protobuf.message.Message): + """The OpAMPConnectionSettings message is a collection of fields which comprise an + offer from the Server to the Agent to use the specified settings for OpAMP + connection. + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DESTINATION_ENDPOINT_FIELD_NUMBER: builtins.int + HEADERS_FIELD_NUMBER: builtins.int + CERTIFICATE_FIELD_NUMBER: builtins.int + HEARTBEAT_INTERVAL_SECONDS_FIELD_NUMBER: builtins.int + destination_endpoint: builtins.str + """OpAMP Server URL This MUST be a WebSocket or HTTP URL and MUST be non-empty, for + example: "wss://example.com:4318/v1/opamp" + """ + @property + def headers(self) -> global___Headers: + """Optional headers to use when connecting. Typically used to set access tokens or + other authorization headers. For HTTP-based protocols the Agent should + set these in the request headers. + For example: + key="Authorization", Value="Basic YWxhZGRpbjpvcGVuc2VzYW1l". + """ + @property + def certificate(self) -> global___TLSCertificate: + """The Agent should use the offered certificate to connect to the destination + from now on. If the Agent is able to validate and connect using the offered + certificate the Agent SHOULD forget any previous client certificates + for this connection. + This field is optional: if omitted the client SHOULD NOT use a client-side certificate. + This field can be used to perform a client certificate revocation/rotation. + """ + heartbeat_interval_seconds: builtins.int + """The Agent MUST periodically send an AgentToServer message if the + AgentCapabilities_ReportsHeartbeat capability is true. At a minimum the instance_uid + field MUST be set. + + An HTTP Client MUST use the value as polling interval, if heartbeat_interval_seconds is non-zero. + + A heartbeat is used to keep the connection active and inform the server that the Agent + is still alive and active. + + If this field has no value or is set to 0, the Agent should not send any heartbeats. + Status: [Development] + """ + def __init__( + self, + *, + destination_endpoint: builtins.str = ..., + headers: global___Headers | None = ..., + certificate: global___TLSCertificate | None = ..., + heartbeat_interval_seconds: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["certificate", b"certificate", "headers", b"headers"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["certificate", b"certificate", "destination_endpoint", b"destination_endpoint", "headers", b"headers", "heartbeat_interval_seconds", b"heartbeat_interval_seconds"]) -> None: ... + +global___OpAMPConnectionSettings = OpAMPConnectionSettings + +@typing_extensions.final +class TelemetryConnectionSettings(google.protobuf.message.Message): + """The TelemetryConnectionSettings message is a collection of fields which comprise an + offer from the Server to the Agent to use the specified settings for a network + connection to report own telemetry. + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DESTINATION_ENDPOINT_FIELD_NUMBER: builtins.int + HEADERS_FIELD_NUMBER: builtins.int + CERTIFICATE_FIELD_NUMBER: builtins.int + destination_endpoint: builtins.str + """The value MUST be a full URL an OTLP/HTTP/Protobuf receiver with path. Schema + SHOULD begin with "https://", for example "https://example.com:4318/v1/metrics" + The Agent MAY refuse to send the telemetry if the URL begins with "http://". + """ + @property + def headers(self) -> global___Headers: + """Optional headers to use when connecting. Typically used to set access tokens or + other authorization headers. For HTTP-based protocols the Agent should + set these in the request headers. + For example: + key="Authorization", Value="Basic YWxhZGRpbjpvcGVuc2VzYW1l". + """ + @property + def certificate(self) -> global___TLSCertificate: + """The Agent should use the offered certificate to connect to the destination + from now on. If the Agent is able to validate and connect using the offered + certificate the Agent SHOULD forget any previous client certificates + for this connection. + This field is optional: if omitted the client SHOULD NOT use a client-side certificate. + This field can be used to perform a client certificate revocation/rotation. + """ + def __init__( + self, + *, + destination_endpoint: builtins.str = ..., + headers: global___Headers | None = ..., + certificate: global___TLSCertificate | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["certificate", b"certificate", "headers", b"headers"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["certificate", b"certificate", "destination_endpoint", b"destination_endpoint", "headers", b"headers"]) -> None: ... + +global___TelemetryConnectionSettings = TelemetryConnectionSettings + +@typing_extensions.final +class OtherConnectionSettings(google.protobuf.message.Message): + """The OtherConnectionSettings message is a collection of fields which comprise an + offer from the Server to the Agent to use the specified settings for a network + connection. It is not required that all fields in this message are specified. + The Server may specify only some of the fields, in which case it means that + the Server offers the Agent to change only those fields, while keeping the + rest of the fields unchanged. + + For example the Server may send a ConnectionSettings message with only the + certificate field set, while all other fields are unset. This means that + the Server wants the Agent to use a new certificate and continue sending to + the destination it is currently sending using the current header and other + settings. + + For fields which reference other messages the field is considered unset + when the reference is unset. + + For primitive field (string) we rely on the "flags" to describe that the + field is not set (this is done to overcome the limitation of old protoc + compilers don't generate methods that allow to check for the presence of + the field. + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class OtherSettingsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + value: builtins.str + def __init__( + self, + *, + key: builtins.str = ..., + value: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + + DESTINATION_ENDPOINT_FIELD_NUMBER: builtins.int + HEADERS_FIELD_NUMBER: builtins.int + CERTIFICATE_FIELD_NUMBER: builtins.int + OTHER_SETTINGS_FIELD_NUMBER: builtins.int + destination_endpoint: builtins.str + """A URL, host:port or some other destination specifier.""" + @property + def headers(self) -> global___Headers: + """Optional headers to use when connecting. Typically used to set access tokens or + other authorization headers. For HTTP-based protocols the Agent should + set these in the request headers. + For example: + key="Authorization", Value="Basic YWxhZGRpbjpvcGVuc2VzYW1l". + """ + @property + def certificate(self) -> global___TLSCertificate: + """The Agent should use the offered certificate to connect to the destination + from now on. If the Agent is able to validate and connect using the offered + certificate the Agent SHOULD forget any previous client certificates + for this connection. + This field is optional: if omitted the client SHOULD NOT use a client-side certificate. + This field can be used to perform a client certificate revocation/rotation. + """ + @property + def other_settings(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: + """Other connection settings. These are Agent-specific and are up to the Agent + interpret. + """ + def __init__( + self, + *, + destination_endpoint: builtins.str = ..., + headers: global___Headers | None = ..., + certificate: global___TLSCertificate | None = ..., + other_settings: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["certificate", b"certificate", "headers", b"headers"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["certificate", b"certificate", "destination_endpoint", b"destination_endpoint", "headers", b"headers", "other_settings", b"other_settings"]) -> None: ... + +global___OtherConnectionSettings = OtherConnectionSettings + +@typing_extensions.final +class Headers(google.protobuf.message.Message): + """Status: [Beta]""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + HEADERS_FIELD_NUMBER: builtins.int + @property + def headers(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Header]: ... + def __init__( + self, + *, + headers: collections.abc.Iterable[global___Header] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["headers", b"headers"]) -> None: ... + +global___Headers = Headers + +@typing_extensions.final +class Header(google.protobuf.message.Message): + """Status: [Beta]""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + value: builtins.str + def __init__( + self, + *, + key: builtins.str = ..., + value: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + +global___Header = Header + +@typing_extensions.final +class TLSCertificate(google.protobuf.message.Message): + """Status: [Beta] + The (cert,private_key) pair should be issued and signed by a Certificate + Authority (CA) that the destination Server recognizes. + + It is highly recommended that the private key of the CA certificate is NOT + stored on the destination Server otherwise compromising the Server will allow + a malicious actor to issue valid Server certificates which will be automatically + trusted by all agents and will allow the actor to trivially MITM Agent-to-Server + traffic of all servers that use this CA certificate for their Server-side + certificates. + + Alternatively the certificate may be self-signed, assuming the Server can + verify the certificate. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CERT_FIELD_NUMBER: builtins.int + PRIVATE_KEY_FIELD_NUMBER: builtins.int + CA_CERT_FIELD_NUMBER: builtins.int + cert: builtins.bytes + """PEM-encoded certificate. Required.""" + private_key: builtins.bytes + """PEM-encoded private key of the certificate. Required.""" + ca_cert: builtins.bytes + """PEM-encoded certificate of the signing CA. + Optional. MUST be specified if the certificate is CA-signed. + Can be stored by TLS-terminating intermediary proxies in order to verify + the connecting client's certificate in the future. + It is not recommended that the Agent accepts this CA as an authority for + any purposes. + """ + def __init__( + self, + *, + cert: builtins.bytes = ..., + private_key: builtins.bytes = ..., + ca_cert: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["ca_cert", b"ca_cert", "cert", b"cert", "private_key", b"private_key"]) -> None: ... + +global___TLSCertificate = TLSCertificate + +@typing_extensions.final +class ConnectionSettingsOffers(google.protobuf.message.Message): + """Status: [Beta]""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class OtherConnectionsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___OtherConnectionSettings: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___OtherConnectionSettings | None = ..., + ) -> 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", "value", b"value"]) -> None: ... + + HASH_FIELD_NUMBER: builtins.int + OPAMP_FIELD_NUMBER: builtins.int + OWN_METRICS_FIELD_NUMBER: builtins.int + OWN_TRACES_FIELD_NUMBER: builtins.int + OWN_LOGS_FIELD_NUMBER: builtins.int + OTHER_CONNECTIONS_FIELD_NUMBER: builtins.int + hash: builtins.bytes + """Hash of all settings, including settings that may be omitted from this message + because they are unchanged. + """ + @property + def opamp(self) -> global___OpAMPConnectionSettings: + """Settings to connect to the OpAMP Server. + If this field is not set then the Agent should assume that the settings are + unchanged and should continue using existing settings. + The Agent MUST verify the offered connection settings by actually connecting + before accepting the setting to ensure it does not loose access to the OpAMP + Server due to invalid settings. + """ + @property + def own_metrics(self) -> global___TelemetryConnectionSettings: + """Settings to connect to an OTLP metrics backend to send Agent's own metrics to. + If this field is not set then the Agent should assume that the settings + are unchanged. + + Once accepted the Agent should periodically send to the specified destination + its own metrics, i.e. metrics of the Agent process and any custom metrics that + describe the Agent state. + + All attributes specified in the identifying_attributes field in AgentDescription + message SHOULD be also specified in the Resource of the reported OTLP metrics. + + Attributes specified in the non_identifying_attributes field in + AgentDescription message may be also specified in the Resource of the reported + OTLP metrics, in which case they SHOULD have exactly the same values. + + Process metrics MUST follow the conventions for processes: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md + """ + @property + def own_traces(self) -> global___TelemetryConnectionSettings: + """Similar to own_metrics, but for traces.""" + @property + def own_logs(self) -> global___TelemetryConnectionSettings: + """Similar to own_metrics, but for logs.""" + @property + def other_connections(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___OtherConnectionSettings]: + """Another set of connection settings, with a string name associated with each. + How the Agent uses these is Agent-specific. Typically the name represents + the name of the destination to connect to (as it is known to the Agent). + If this field is not set then the Agent should assume that the other_connections + settings are unchanged. + """ + def __init__( + self, + *, + hash: builtins.bytes = ..., + opamp: global___OpAMPConnectionSettings | None = ..., + own_metrics: global___TelemetryConnectionSettings | None = ..., + own_traces: global___TelemetryConnectionSettings | None = ..., + own_logs: global___TelemetryConnectionSettings | None = ..., + other_connections: collections.abc.Mapping[builtins.str, global___OtherConnectionSettings] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["opamp", b"opamp", "own_logs", b"own_logs", "own_metrics", b"own_metrics", "own_traces", b"own_traces"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["hash", b"hash", "opamp", b"opamp", "other_connections", b"other_connections", "own_logs", b"own_logs", "own_metrics", b"own_metrics", "own_traces", b"own_traces"]) -> None: ... + +global___ConnectionSettingsOffers = ConnectionSettingsOffers + +@typing_extensions.final +class PackagesAvailable(google.protobuf.message.Message): + """List of packages that the Server offers to the Agent. + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class PackagesEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___PackageAvailable: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___PackageAvailable | None = ..., + ) -> 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", "value", b"value"]) -> None: ... + + PACKAGES_FIELD_NUMBER: builtins.int + ALL_PACKAGES_HASH_FIELD_NUMBER: builtins.int + @property + def packages(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___PackageAvailable]: + """Map of packages. Keys are package names, values are the packages available for download.""" + all_packages_hash: builtins.bytes + """Aggregate hash of all remotely installed packages. The Agent SHOULD include this + value in subsequent PackageStatuses messages. This in turn allows the management + Server to identify that a different set of packages is available for the Agent + and specify the available packages in the next ServerToAgent message. + + This field MUST be always set if the management Server supports packages + of agents. + + The hash is calculated as an aggregate of all packages names and content. + """ + def __init__( + self, + *, + packages: collections.abc.Mapping[builtins.str, global___PackageAvailable] | None = ..., + all_packages_hash: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["all_packages_hash", b"all_packages_hash", "packages", b"packages"]) -> None: ... + +global___PackagesAvailable = PackagesAvailable + +@typing_extensions.final +class PackageAvailable(google.protobuf.message.Message): + """Each Agent is composed of one or more packages. A package has a name and + content stored in a file. The content of the files, functionality + provided by the packages, how they are stored and used by the Agent side is Agent + type-specific and is outside the concerns of the OpAMP protocol. + + If the Agent does not have an installed package with the specified name then + it SHOULD download it from the specified URL and install it. + + If the Agent already has an installed package with the specified name + but with a different hash then the Agent SHOULD download and + install the package again, since it is a different version of the same package. + + If the Agent has an installed package with the specified name and the same + hash then the Agent does not need to do anything, it already + has the right version of the package. + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TYPE_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + FILE_FIELD_NUMBER: builtins.int + HASH_FIELD_NUMBER: builtins.int + type: global___PackageType.ValueType + version: builtins.str + """The package version that is available on the Server side. The Agent may for + example use this information to avoid downloading a package that was previously + already downloaded and failed to install. + """ + @property + def file(self) -> global___DownloadableFile: + """The downloadable file of the package.""" + hash: builtins.bytes + """The hash of the package. SHOULD be calculated based on all other fields of the + PackageAvailable message and content of the file of the package. The hash is + used by the Agent to determine if the package it has is different from the + package the Server is offering. + """ + def __init__( + self, + *, + type: global___PackageType.ValueType = ..., + version: builtins.str = ..., + file: global___DownloadableFile | None = ..., + hash: builtins.bytes = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["file", b"file"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["file", b"file", "hash", b"hash", "type", b"type", "version", b"version"]) -> None: ... + +global___PackageAvailable = PackageAvailable + +@typing_extensions.final +class DownloadableFile(google.protobuf.message.Message): + """Status: [Beta]""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DOWNLOAD_URL_FIELD_NUMBER: builtins.int + CONTENT_HASH_FIELD_NUMBER: builtins.int + SIGNATURE_FIELD_NUMBER: builtins.int + HEADERS_FIELD_NUMBER: builtins.int + download_url: builtins.str + """The URL from which the file can be downloaded using HTTP GET request. + The Server at the specified URL SHOULD support range requests + to allow for resuming downloads. + """ + content_hash: builtins.bytes + """The hash of the file content. Can be used by the Agent to verify that the file + was downloaded correctly. + """ + signature: builtins.bytes + """Optional signature of the file content. Can be used by the Agent to verify the + authenticity of the downloaded file, for example can be the + [detached GPG signature](https://www.gnupg.org/gph/en/manual/x135.html#AEN160). + The exact signing and verification method is Agent specific. See + https://github.com/open-telemetry/opamp-spec/blob/main/specification.md#code-signing + for recommendations. + """ + @property + def headers(self) -> global___Headers: + """Optional headers to use when downloading a file. Typically used to set + access tokens or other authorization headers. For HTTP-based protocols + the Agent should set these in the request headers. + For example: + key="Authorization", Value="Basic YWxhZGRpbjpvcGVuc2VzYW1l". + Status: [Development] + """ + def __init__( + self, + *, + download_url: builtins.str = ..., + content_hash: builtins.bytes = ..., + signature: builtins.bytes = ..., + headers: global___Headers | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["headers", b"headers"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["content_hash", b"content_hash", "download_url", b"download_url", "headers", b"headers", "signature", b"signature"]) -> None: ... + +global___DownloadableFile = DownloadableFile + +@typing_extensions.final +class ServerErrorResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TYPE_FIELD_NUMBER: builtins.int + ERROR_MESSAGE_FIELD_NUMBER: builtins.int + RETRY_INFO_FIELD_NUMBER: builtins.int + type: global___ServerErrorResponseType.ValueType + error_message: builtins.str + """Error message in the string form, typically human readable.""" + @property + def retry_info(self) -> global___RetryInfo: + """Additional information about retrying if type==UNAVAILABLE.""" + def __init__( + self, + *, + type: global___ServerErrorResponseType.ValueType = ..., + error_message: builtins.str = ..., + retry_info: global___RetryInfo | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["Details", b"Details", "retry_info", b"retry_info"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["Details", b"Details", "error_message", b"error_message", "retry_info", b"retry_info", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["Details", b"Details"]) -> typing_extensions.Literal["retry_info"] | None: ... + +global___ServerErrorResponse = ServerErrorResponse + +@typing_extensions.final +class RetryInfo(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RETRY_AFTER_NANOSECONDS_FIELD_NUMBER: builtins.int + retry_after_nanoseconds: builtins.int + def __init__( + self, + *, + retry_after_nanoseconds: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["retry_after_nanoseconds", b"retry_after_nanoseconds"]) -> None: ... + +global___RetryInfo = RetryInfo + +@typing_extensions.final +class ServerToAgentCommand(google.protobuf.message.Message): + """ServerToAgentCommand is sent from the Server to the Agent to request that the Agent + perform a command. + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TYPE_FIELD_NUMBER: builtins.int + type: global___CommandType.ValueType + def __init__( + self, + *, + type: global___CommandType.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["type", b"type"]) -> None: ... + +global___ServerToAgentCommand = ServerToAgentCommand + +@typing_extensions.final +class AgentDescription(google.protobuf.message.Message): + """////////////////////////////////////////////////////////////////////////////////// + Status reporting + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + IDENTIFYING_ATTRIBUTES_FIELD_NUMBER: builtins.int + NON_IDENTIFYING_ATTRIBUTES_FIELD_NUMBER: builtins.int + @property + def identifying_attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[anyvalue_pb2.KeyValue]: + """Attributes that identify the Agent. + Keys/values are according to OpenTelemetry semantic conventions, see: + https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions + + For standalone running Agents (such as OpenTelemetry Collector) the following + attributes SHOULD be specified: + - service.name should be set to a reverse FQDN that uniquely identifies the + Agent type, e.g. "io.opentelemetry.collector" + - service.namespace if it is used in the environment where the Agent runs. + - service.version should be set to version number of the Agent build. + - service.instance.id should be set. It may be set equal to the Agent's + instance uid (equal to ServerToAgent.instance_uid field) or any other value + that uniquely identifies the Agent in combination with other attributes. + - any other attributes that are necessary for uniquely identifying the Agent's + own telemetry. + + The Agent SHOULD also include these attributes in the Resource of its own + telemetry. The combination of identifying attributes SHOULD be sufficient to + uniquely identify the Agent's own telemetry in the destination system to which + the Agent sends its own telemetry. + """ + @property + def non_identifying_attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[anyvalue_pb2.KeyValue]: + """Attributes that do not necessarily identify the Agent but help describe + where it runs. + The following attributes SHOULD be included: + - os.type, os.version - to describe where the Agent runs. + - host.* to describe the host the Agent runs on. + - cloud.* to describe the cloud where the host is located. + - any other relevant Resource attributes that describe this Agent and the + environment it runs in. + - any user-defined attributes that the end user would like to associate + with this Agent. + """ + def __init__( + self, + *, + identifying_attributes: collections.abc.Iterable[anyvalue_pb2.KeyValue] | None = ..., + non_identifying_attributes: collections.abc.Iterable[anyvalue_pb2.KeyValue] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["identifying_attributes", b"identifying_attributes", "non_identifying_attributes", b"non_identifying_attributes"]) -> None: ... + +global___AgentDescription = AgentDescription + +@typing_extensions.final +class ComponentHealth(google.protobuf.message.Message): + """The health of the Agent and sub-components + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class ComponentHealthMapEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___ComponentHealth: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___ComponentHealth | None = ..., + ) -> 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", "value", b"value"]) -> None: ... + + HEALTHY_FIELD_NUMBER: builtins.int + START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + LAST_ERROR_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + STATUS_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + COMPONENT_HEALTH_MAP_FIELD_NUMBER: builtins.int + healthy: builtins.bool + """Set to true if the component is up and healthy.""" + start_time_unix_nano: builtins.int + """Timestamp since the component is up, i.e. when the component was started. + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. + If the component is not running MUST be set to 0. + """ + last_error: builtins.str + """Human-readable error message if the component is in erroneous state. SHOULD be set + when healthy==false. + """ + status: builtins.str + """Component status represented as a string. The status values are defined by agent-specific + semantics and not at the protocol level. + """ + status_time_unix_nano: builtins.int + """The time when the component status was observed. Value is UNIX Epoch time in + nanoseconds since 00:00:00 UTC on 1 January 1970. + """ + @property + def component_health_map(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___ComponentHealth]: + """A map to store more granular, sub-component health. It can nest as deeply as needed to + describe the underlying system. + """ + def __init__( + self, + *, + healthy: builtins.bool = ..., + start_time_unix_nano: builtins.int = ..., + last_error: builtins.str = ..., + status: builtins.str = ..., + status_time_unix_nano: builtins.int = ..., + component_health_map: collections.abc.Mapping[builtins.str, global___ComponentHealth] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["component_health_map", b"component_health_map", "healthy", b"healthy", "last_error", b"last_error", "start_time_unix_nano", b"start_time_unix_nano", "status", b"status", "status_time_unix_nano", b"status_time_unix_nano"]) -> None: ... + +global___ComponentHealth = ComponentHealth + +@typing_extensions.final +class EffectiveConfig(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CONFIG_MAP_FIELD_NUMBER: builtins.int + @property + def config_map(self) -> global___AgentConfigMap: + """The effective config of the Agent.""" + def __init__( + self, + *, + config_map: global___AgentConfigMap | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["config_map", b"config_map"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["config_map", b"config_map"]) -> None: ... + +global___EffectiveConfig = EffectiveConfig + +@typing_extensions.final +class RemoteConfigStatus(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LAST_REMOTE_CONFIG_HASH_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + ERROR_MESSAGE_FIELD_NUMBER: builtins.int + last_remote_config_hash: builtins.bytes + """The hash of the remote config that was last received by this Agent in the + AgentRemoteConfig.config_hash field. + The Server SHOULD compare this hash with the config hash + it has for the Agent and if the hashes are different the Server MUST include + the remote_config field in the response in the ServerToAgent message. + """ + status: global___RemoteConfigStatuses.ValueType + error_message: builtins.str + """Optional error message if status==FAILED.""" + def __init__( + self, + *, + last_remote_config_hash: builtins.bytes = ..., + status: global___RemoteConfigStatuses.ValueType = ..., + error_message: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "last_remote_config_hash", b"last_remote_config_hash", "status", b"status"]) -> None: ... + +global___RemoteConfigStatus = RemoteConfigStatus + +@typing_extensions.final +class PackageStatuses(google.protobuf.message.Message): + """The PackageStatuses message describes the status of all packages that the Agent + has or was offered. + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class PackagesEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___PackageStatus: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___PackageStatus | None = ..., + ) -> 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", "value", b"value"]) -> None: ... + + PACKAGES_FIELD_NUMBER: builtins.int + SERVER_PROVIDED_ALL_PACKAGES_HASH_FIELD_NUMBER: builtins.int + ERROR_MESSAGE_FIELD_NUMBER: builtins.int + @property + def packages(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___PackageStatus]: + """A map of PackageStatus messages, where the keys are package names. + The key MUST match the name field of PackageStatus message. + """ + server_provided_all_packages_hash: builtins.bytes + """The aggregate hash of all packages that this Agent previously received from the + Server via PackagesAvailable message. + + The Server SHOULD compare this hash to the aggregate hash of all packages that + it has for this Agent and if the hashes are different the Server SHOULD send + an PackagesAvailable message to the Agent. + """ + error_message: builtins.str + """This field is set if the Agent encountered an error when processing the + PackagesAvailable message and that error is not related to any particular single + package. + The field must be unset is there were no processing errors. + """ + def __init__( + self, + *, + packages: collections.abc.Mapping[builtins.str, global___PackageStatus] | None = ..., + server_provided_all_packages_hash: builtins.bytes = ..., + error_message: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "packages", b"packages", "server_provided_all_packages_hash", b"server_provided_all_packages_hash"]) -> None: ... + +global___PackageStatuses = PackageStatuses + +@typing_extensions.final +class PackageStatus(google.protobuf.message.Message): + """The status of a single package. + Status: [Beta] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + AGENT_HAS_VERSION_FIELD_NUMBER: builtins.int + AGENT_HAS_HASH_FIELD_NUMBER: builtins.int + SERVER_OFFERED_VERSION_FIELD_NUMBER: builtins.int + SERVER_OFFERED_HASH_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + ERROR_MESSAGE_FIELD_NUMBER: builtins.int + DOWNLOAD_DETAILS_FIELD_NUMBER: builtins.int + name: builtins.str + """Package name. MUST be always set and MUST match the key in the packages field + of PackageStatuses message. + """ + agent_has_version: builtins.str + """The version of the package that the Agent has. + MUST be set if the Agent has this package. + MUST be empty if the Agent does not have this package. This may be the case + for example if the package was offered by the Server but failed to install + and the Agent did not have this package previously. + """ + agent_has_hash: builtins.bytes + """The hash of the package that the Agent has. + MUST be set if the Agent has this package. + MUST be empty if the Agent does not have this package. This may be the case for + example if the package was offered by the Server but failed to install and the + Agent did not have this package previously. + """ + server_offered_version: builtins.str + """The version of the package that the Server offered to the Agent. + MUST be set if the installation of the package is initiated by an earlier offer + from the Server to install this package. + + MUST be empty if the Agent has this package but it was installed locally and + was not offered by the Server. + + Note that it is possible for both agent_has_version and server_offered_version + fields to be set and to have different values. This is for example possible if + the Agent already has a version of the package successfully installed, the Server + offers a different version, but the Agent fails to install that version. + """ + server_offered_hash: builtins.bytes + """The hash of the package that the Server offered to the Agent. + MUST be set if the installation of the package is initiated by an earlier + offer from the Server to install this package. + + MUST be empty if the Agent has this package but it was installed locally and + was not offered by the Server. + + Note that it is possible for both agent_has_hash and server_offered_hash + fields to be set and to have different values. This is for example possible if + the Agent already has a version of the package successfully installed, the + Server offers a different version, but the Agent fails to install that version. + """ + status: global___PackageStatusEnum.ValueType + error_message: builtins.str + """Error message if the status is erroneous.""" + @property + def download_details(self) -> global___PackageDownloadDetails: + """Optional details that may be of interest to a user. + Should only be set if status is Downloading. + Status: [Development] + """ + def __init__( + self, + *, + name: builtins.str = ..., + agent_has_version: builtins.str = ..., + agent_has_hash: builtins.bytes = ..., + server_offered_version: builtins.str = ..., + server_offered_hash: builtins.bytes = ..., + status: global___PackageStatusEnum.ValueType = ..., + error_message: builtins.str = ..., + download_details: global___PackageDownloadDetails | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["download_details", b"download_details"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["agent_has_hash", b"agent_has_hash", "agent_has_version", b"agent_has_version", "download_details", b"download_details", "error_message", b"error_message", "name", b"name", "server_offered_hash", b"server_offered_hash", "server_offered_version", b"server_offered_version", "status", b"status"]) -> None: ... + +global___PackageStatus = PackageStatus + +@typing_extensions.final +class PackageDownloadDetails(google.protobuf.message.Message): + """Additional details that an agent can use to describe an in-progress package download. + Status: [Development] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DOWNLOAD_PERCENT_FIELD_NUMBER: builtins.int + DOWNLOAD_BYTES_PER_SECOND_FIELD_NUMBER: builtins.int + download_percent: builtins.float + """The package download progress as a percentage.""" + download_bytes_per_second: builtins.float + """The current package download rate in bytes per second.""" + def __init__( + self, + *, + download_percent: builtins.float = ..., + download_bytes_per_second: builtins.float = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["download_bytes_per_second", b"download_bytes_per_second", "download_percent", b"download_percent"]) -> None: ... + +global___PackageDownloadDetails = PackageDownloadDetails + +@typing_extensions.final +class AgentIdentification(google.protobuf.message.Message): + """Properties related to identification of the Agent, which can be overridden + by the Server if needed + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NEW_INSTANCE_UID_FIELD_NUMBER: builtins.int + new_instance_uid: builtins.bytes + """When new_instance_uid is set, Agent MUST update instance_uid + to the value provided and use it for all further communication. + MUST be 16 bytes long and SHOULD be generated using the UUID v7 spec. + """ + def __init__( + self, + *, + new_instance_uid: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["new_instance_uid", b"new_instance_uid"]) -> None: ... + +global___AgentIdentification = AgentIdentification + +@typing_extensions.final +class AgentRemoteConfig(google.protobuf.message.Message): + """/////////////////////////////////////////////////////////////////////////////////// + Config messages + /////////////////////////////////////////////////////////////////////////////////// + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CONFIG_FIELD_NUMBER: builtins.int + CONFIG_HASH_FIELD_NUMBER: builtins.int + @property + def config(self) -> global___AgentConfigMap: + """Agent config offered by the management Server to the Agent instance. SHOULD NOT be + set if the config for this Agent has not changed since it was last requested (i.e. + AgentConfigRequest.last_remote_config_hash field is equal to + AgentConfigResponse.config_hash field). + """ + config_hash: builtins.bytes + """Hash of "config". The Agent SHOULD include this value in subsequent + RemoteConfigStatus messages in the last_remote_config_hash field. This in turn + allows the management Server to identify that a new config is available for the Agent. + + This field MUST be always set if the management Server supports remote configuration + of agents. + + Management Server must choose a hashing function that guarantees lack of hash + collisions in practice. + """ + def __init__( + self, + *, + config: global___AgentConfigMap | None = ..., + config_hash: builtins.bytes = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["config", b"config"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["config", b"config", "config_hash", b"config_hash"]) -> None: ... + +global___AgentRemoteConfig = AgentRemoteConfig + +@typing_extensions.final +class AgentConfigMap(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class ConfigMapEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___AgentConfigFile: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___AgentConfigFile | None = ..., + ) -> 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", "value", b"value"]) -> None: ... + + CONFIG_MAP_FIELD_NUMBER: builtins.int + @property + def config_map(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___AgentConfigFile]: + """Map of configs. Keys are config file names or config section names. + The configuration is assumed to be a collection of one or more named config files + or sections. + For agents that use a single config file or section the map SHOULD contain a single + entry and the key may be an empty string. + """ + def __init__( + self, + *, + config_map: collections.abc.Mapping[builtins.str, global___AgentConfigFile] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["config_map", b"config_map"]) -> None: ... + +global___AgentConfigMap = AgentConfigMap + +@typing_extensions.final +class AgentConfigFile(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BODY_FIELD_NUMBER: builtins.int + CONTENT_TYPE_FIELD_NUMBER: builtins.int + body: builtins.bytes + """Config file or section body. The content, format and encoding depends on the Agent + type. The content_type field may optionally describe the MIME type of the body. + """ + content_type: builtins.str + """Optional MIME Content-Type that describes what's in the body field, for + example "text/yaml". + """ + def __init__( + self, + *, + body: builtins.bytes = ..., + content_type: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["body", b"body", "content_type", b"content_type"]) -> None: ... + +global___AgentConfigFile = AgentConfigFile + +@typing_extensions.final +class CustomCapabilities(google.protobuf.message.Message): + """/////////////////////////////////////////////////////////////////////////////////// + Custom messages + /////////////////////////////////////////////////////////////////////////////////// + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CAPABILITIES_FIELD_NUMBER: builtins.int + @property + def capabilities(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """A list of custom capabilities that are supported. Each capability is a reverse FQDN + with optional version information that uniquely identifies the custom capability + and should match a capability specified in a supported CustomMessage. + Status: [Development] + """ + def __init__( + self, + *, + capabilities: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["capabilities", b"capabilities"]) -> None: ... + +global___CustomCapabilities = CustomCapabilities + +@typing_extensions.final +class CustomMessage(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CAPABILITY_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + DATA_FIELD_NUMBER: builtins.int + capability: builtins.str + """A reverse FQDN that uniquely identifies the capability and matches one of the + capabilities in the CustomCapabilities message. + Status: [Development] + """ + type: builtins.str + """Type of message within the capability. The capability defines the types of custom + messages that are used to implement the capability. The type must only be unique + within the capability. + Status: [Development] + """ + data: builtins.bytes + """Binary data of the message. The capability must specify the format of the contents + of the data for each custom message type it defines. + Status: [Development] + """ + def __init__( + self, + *, + capability: builtins.str = ..., + type: builtins.str = ..., + data: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["capability", b"capability", "data", b"data", "type", b"type"]) -> None: ... + +global___CustomMessage = CustomMessage diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/base.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/base.py new file mode 100644 index 00000000000..ac4e6866bc7 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/base.py @@ -0,0 +1,40 @@ +# 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 __future__ import annotations + +import abc +from typing import Mapping + +from opentelemetry._opamp.proto import opamp_pb2 + +base_headers = { + "Content-Type": "application/x-protobuf", +} + + +class HttpTransport(abc.ABC): + @abc.abstractmethod + def send( + self, + *, + url: str, + headers: Mapping[str, str], + data: bytes, + timeout_millis: int, + tls_certificate: str | bool, + tls_client_certificate: str | None = None, + tls_client_key: str | None = None, + ) -> opamp_pb2.ServerToAgent: + pass diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/exceptions.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/exceptions.py new file mode 100644 index 00000000000..e57aeb53f7c --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/exceptions.py @@ -0,0 +1,17 @@ +# 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. + + +class OpAMPException(Exception): + pass diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/requests.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/requests.py new file mode 100644 index 00000000000..974da6906b3 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/requests.py @@ -0,0 +1,67 @@ +# 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 __future__ import annotations + +import logging +from typing import Mapping + +import requests + +from opentelemetry._opamp import messages +from opentelemetry._opamp.transport.base import HttpTransport, base_headers +from opentelemetry._opamp.transport.exceptions import OpAMPException + +logger = logging.getLogger(__name__) + + +class RequestsTransport(HttpTransport): + def __init__(self, session: requests.Session | None = None): + self.session = requests.Session() if session is None else session + + def send( + self, + *, + url: str, + headers: Mapping[str, str], + data: bytes, + timeout_millis: int, + tls_certificate: str | bool, + tls_client_certificate: str | None = None, + tls_client_key: str | None = None, + ): + headers = {**base_headers, **headers} + timeout: float = timeout_millis / 1e3 + client_cert = ( + (tls_client_certificate, tls_client_key) + if tls_client_certificate and tls_client_key + else tls_client_certificate + ) + try: + response = self.session.post( + url, + headers=headers, + data=data, + timeout=timeout, + verify=tls_certificate, + cert=client_cert, + ) + response.raise_for_status() + except Exception as exc: + logger.error(str(exc)) + raise OpAMPException + + message = messages.decode_message(response.content) + + return message diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py new file mode 100644 index 00000000000..e7bf4a48eb5 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py @@ -0,0 +1,15 @@ +# 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. + +__version__ = "0.1b0.dev" diff --git a/opamp/opentelemetry-opamp-client/test-requirements.in b/opamp/opentelemetry-opamp-client/test-requirements.in new file mode 100644 index 00000000000..67c1f299b84 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/test-requirements.in @@ -0,0 +1,18 @@ +colorama>=0.4.6 +iniconfig>=2.0.0 +packaging>=24.0 +pluggy>=1.5.0 +protobuf>=5.29.5 +pytest>=7.4.4 +pytest-vcr>=1.0.2 ; python_version > '3.9' and platform_python_implementation !='PyPy' +pyyaml>=6.0.2 +vcrpy>=7.0.0 ; python_version > '3.9' and platform_python_implementation !='PyPy' +yarl>=1.20.1 +requests>=2.32.2 +urllib3>=2.5.0 +uuid-utils>=0.11.0 +wrapt>=1.16.0 +-e opamp/opentelemetry-opamp-client + +# for pylint +tomli>=1.1.0 diff --git a/opamp/opentelemetry-opamp-client/test-requirements.latest.txt b/opamp/opentelemetry-opamp-client/test-requirements.latest.txt new file mode 100644 index 00000000000..8c2e2951286 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/test-requirements.latest.txt @@ -0,0 +1,87 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile --python 3.9 --universal -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.latest.txt +-e opamp/opentelemetry-opamp-client + # via -r opamp/opentelemetry-opamp-client/test-requirements.in +certifi==2025.7.9 + # via requests +charset-normalizer==3.4.2 + # via requests +colorama==0.4.6 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +exceptiongroup==1.3.0 ; python_full_version < '3.11' + # via pytest +idna==3.10 + # via + # requests + # yarl +importlib-metadata==8.7.0 + # via opentelemetry-api +iniconfig==2.1.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +multidict==6.6.3 + # via yarl +packaging==25.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +pluggy==1.6.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +propcache==0.3.2 + # via yarl +protobuf==6.31.1 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # opentelemetry-opamp-client +pytest==7.4.4 + # via + # -c dev-requirements.txt + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest-vcr +pytest-vcr==1.0.2 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' + # via -r opamp/opentelemetry-opamp-client/test-requirements.in +pyyaml==6.0.2 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # vcrpy +requests==2.32.3 + # via + # -c dev-requirements.txt + # -r opamp/opentelemetry-opamp-client/test-requirements.in +tomli==2.2.1 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +typing-extensions==4.14.0 + # via + # exceptiongroup + # multidict + # opentelemetry-api +urllib3==2.5.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # requests + # vcrpy +uuid-utils==0.11.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # opentelemetry-opamp-client +vcrpy==7.0.0 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest-vcr +wrapt==1.17.2 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # vcrpy +yarl==1.20.1 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # vcrpy +zipp==3.23.0 + # via importlib-metadata diff --git a/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt b/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt new file mode 100644 index 00000000000..914aae89556 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt @@ -0,0 +1,83 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile --python 3.9 --universal --resolution lowest -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.lowest.txt +-e opamp/opentelemetry-opamp-client + # via -r opamp/opentelemetry-opamp-client/test-requirements.in +certifi==2017.4.17 + # via requests +charset-normalizer==2.0.0 + # via requests +colorama==0.4.6 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +deprecated==1.2.6 + # via opentelemetry-api +exceptiongroup==1.0.0 ; python_full_version < '3.11' + # via pytest +idna==2.5 + # via + # requests + # yarl +iniconfig==2.0.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +multidict==4.0.0 + # via yarl +packaging==24.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +pluggy==1.5.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +propcache==0.2.1 + # via yarl +protobuf==5.29.5 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # opentelemetry-opamp-client +pytest==7.4.4 + # via + # -c dev-requirements.txt + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest-vcr +pytest-vcr==1.0.2 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' + # via -r opamp/opentelemetry-opamp-client/test-requirements.in +pyyaml==6.0.2 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # vcrpy +requests==2.32.3 + # via + # -c dev-requirements.txt + # -r opamp/opentelemetry-opamp-client/test-requirements.in +setuptools==16.0 + # via opentelemetry-api +tomli==1.1.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest +urllib3==2.5.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # requests + # vcrpy +uuid-utils==0.11.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # opentelemetry-opamp-client +vcrpy==7.0.0 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # pytest-vcr +wrapt==1.16.0 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # deprecated + # vcrpy +yarl==1.20.1 + # via + # -r opamp/opentelemetry-opamp-client/test-requirements.in + # vcrpy diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/README.md b/opamp/opentelemetry-opamp-client/tests/opamp/README.md new file mode 100644 index 00000000000..b36067236ec --- /dev/null +++ b/opamp/opentelemetry-opamp-client/tests/opamp/README.md @@ -0,0 +1,23 @@ +## How to record tests cassettes + +### Run the server + +Checkout [opentelemetry-go](https://github.com/open-telemetry/opentelemetry-go) and build it with: + +``` +make +``` + +Then run the example server with: + +``` +./internal/examples/server/bin/server +``` + +### Record the cassettes + +We are using `vcr.py` for recording HTTP responses from the server, it works by serializing the response in a yaml file and then replying +it. `vcr.py` will record a new cassettes only if it does not find it so to redo a recording you need to delete the recording in the +`cassettes/` directory. + +Because of vcr.py issues with older urllib3 versions tests are skipped with Python older than 3.10. diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/cassettes/test_connection_remote_config_status_heartbeat_disconnection.yaml b/opamp/opentelemetry-opamp-client/tests/opamp/cassettes/test_connection_remote_config_status_heartbeat_disconnection.yaml new file mode 100644 index 00000000000..74db5d2d221 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/tests/opamp/cassettes/test_connection_remote_config_status_heartbeat_disconnection.yaml @@ -0,0 +1,136 @@ +interactions: +- request: + body: !!binary | + ChABnL5b5k5046/FazbAJ7r4Gj0KFQoMc2VydmljZS5uYW1lEgUKA2ZvbwokChtkZXBsb3ltZW50 + LmVudmlyb25tZW50Lm5hbWUSBQoDZm9vIIdg + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '84' + Content-Type: + - application/x-protobuf + User-Agent: + - OTel-OpAMP-Python/0.1b0.dev + method: POST + uri: https://localhost:4320/v1/opamp + response: + body: + string: !!binary | + ChABnL5b5k5046/FazbAJ7r4GioKBgoECgASABIg47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZ + G3hSuFUwAVIA + headers: + Content-Length: + - '66' + Content-Type: + - application/x-protobuf + Date: + - Thu, 05 Mar 2026 14:16:59 GMT + status: + code: 200 + message: OK +- request: + body: !!binary | + ChABnL5b5k5046/FazbAJ7r4EAEgh2A6JAog47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hS + uFUQAQ== + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '61' + Content-Type: + - application/x-protobuf + User-Agent: + - OTel-OpAMP-Python/0.1b0.dev + method: POST + uri: https://localhost:4320/v1/opamp + response: + body: + string: !!binary | + ChABnL5b5k5046/FazbAJ7r4GioKBgoECgASABIg47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZ + G3hSuFUwAVIA + headers: + Content-Length: + - '66' + Content-Type: + - application/x-protobuf + Date: + - Thu, 05 Mar 2026 14:16:59 GMT + status: + code: 200 + message: OK +- request: + body: !!binary | + ChABnL5b5k5046/FazbAJ7r4EAIgh2A= + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '23' + Content-Type: + - application/x-protobuf + User-Agent: + - OTel-OpAMP-Python/0.1b0.dev + method: POST + uri: https://localhost:4320/v1/opamp + response: + body: + string: !!binary | + ChABnL5b5k5046/FazbAJ7r4GioKBgoECgASABIg47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZ + G3hSuFUwAVIA + headers: + Content-Length: + - '66' + Content-Type: + - application/x-protobuf + Date: + - Thu, 05 Mar 2026 14:17:00 GMT + status: + code: 200 + message: OK +- request: + body: !!binary | + ChABnL5b5k5046/FazbAJ7r4EAMgh2BKAA== + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '25' + Content-Type: + - application/x-protobuf + User-Agent: + - OTel-OpAMP-Python/0.1b0.dev + method: POST + uri: https://localhost:4320/v1/opamp + response: + body: + string: !!binary | + ChABnL5b5k5046/FazbAJ7r4GioKBgoECgASABIg47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZ + G3hSuFUwAVIA + headers: + Content-Length: + - '66' + Content-Type: + - application/x-protobuf + Date: + - Thu, 05 Mar 2026 14:17:01 GMT + status: + code: 200 + message: OK +version: 1 diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/conftest.py b/opamp/opentelemetry-opamp-client/tests/opamp/conftest.py new file mode 100644 index 00000000000..790f97f8e54 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/tests/opamp/conftest.py @@ -0,0 +1,33 @@ +# 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. + +import pytest + + +@pytest.fixture(scope="module") +def vcr_config(): + return { + "filter_headers": [ + ("authorization", "Bearer key"), + ], + "decode_compressed_response": True, + "before_record_response": scrub_response_headers, + } + + +def scrub_response_headers(response): + """ + This scrubs sensitive response headers. Note they are case-sensitive! + """ + return response diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py new file mode 100644 index 00000000000..95821511767 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py @@ -0,0 +1,210 @@ +# 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. + +import logging +from time import sleep +from unittest import mock + +from opentelemetry._opamp.agent import OpAMPAgent +from opentelemetry._opamp.agent import _Job as Job + + +def test_can_instantiate_agent(): + agent = OpAMPAgent( + interval=30, client=mock.Mock(), message_handler=mock.Mock() + ) + assert isinstance(agent, OpAMPAgent) + + +def test_can_start_agent(): + agent = OpAMPAgent( + interval=30, client=mock.Mock(), message_handler=mock.Mock() + ) + agent.start() + agent.stop() + + +def test_agent_start_will_send_connection_and_disconnetion_messages(): + client_mock = mock.Mock() + mock_message = {"mock": "message"} + client_mock.send.return_value = mock_message + message_handler = mock.Mock() + agent = OpAMPAgent( + interval=30, client=client_mock, message_handler=message_handler + ) + agent.start() + # wait for the queue to be consumed + sleep(0.1) + agent.stop() + + # one send for connection message, one for disconnect agent message + assert client_mock.send.call_count == 2 + # connection callback has been called + assert agent._schedule is True + # connection message response has been received + message_handler.assert_called_once_with(agent, client_mock, mock_message) + + +def test_agent_can_call_agent_stop_multiple_times(): + agent = OpAMPAgent( + interval=30, client=mock.Mock(), message_handler=mock.Mock() + ) + agent.start() + agent.stop() + agent.stop() + + +def test_agent_can_call_agent_stop_before_start(): + agent = OpAMPAgent( + interval=30, client=mock.Mock(), message_handler=mock.Mock() + ) + agent.stop() + + +def test_agent_send_warns_without_worker_thread(caplog): + agent = OpAMPAgent( + interval=30, client=mock.Mock(), message_handler=mock.Mock() + ) + agent.send(payload="payload") + + assert caplog.record_tuples == [ + ( + "opentelemetry._opamp.agent", + logging.WARNING, + "Called send() but worker thread is not alive. Worker threads is started with start()", + ) + ] + + +def test_agent_retries_before_max_attempts(caplog): + caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") + message_handler_mock = mock.Mock() + client_mock = mock.Mock() + connection_message = disconnection_message = server_message = mock.Mock() + client_mock.send.side_effect = [ + connection_message, + Exception, + server_message, + disconnection_message, + ] + agent = OpAMPAgent( + interval=30, + client=client_mock, + message_handler=message_handler_mock, + initial_backoff=0, + ) + agent.start() + agent.send(payload="payload") + # wait for the queue to be consumed + sleep(0.1) + agent.stop() + + assert client_mock.send.call_count == 4 + assert message_handler_mock.call_count == 2 + + +def test_agent_stops_after_max_attempts(caplog): + caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") + message_handler_mock = mock.Mock() + client_mock = mock.Mock() + connection_message = disconnection_message = mock.Mock() + client_mock.send.side_effect = [ + connection_message, + Exception, + Exception, + disconnection_message, + ] + agent = OpAMPAgent( + interval=30, + client=client_mock, + message_handler=message_handler_mock, + max_retries=1, + initial_backoff=0, + ) + agent.start() + agent.send(payload="payload") + # wait for the queue to be consumed + sleep(0.1) + agent.stop() + + assert client_mock.send.call_count == 4 + assert message_handler_mock.call_count == 1 + + +def test_agent_send_enqueues_job(): + message_handler_mock = mock.Mock() + agent = OpAMPAgent( + interval=30, client=mock.Mock(), message_handler=message_handler_mock + ) + agent.start() + # wait for the queue to be consumed + sleep(0.1) + # message handler called for connection message + assert message_handler_mock.call_count == 1 + agent.send(payload="payload") + # wait for the queue to be consumed + sleep(0.1) + agent.stop() + + # message handler called once for connection and once for our message + assert message_handler_mock.call_count == 2 + + +def test_can_instantiate_job(): + job = Job(payload="payload") + + assert isinstance(job, Job) + + +def test_job_should_retry(): + job = Job(payload="payload") + assert job.attempt == 0 + assert job.max_retries == 1 + assert job.should_retry() is True + + job.attempt += 1 + assert job.should_retry() is True + + job.attempt += 1 + assert job.should_retry() is False + + +def test_job_delay(): + job = Job(payload="payload") + + assert job.initial_backoff == 1 + job.attempt = 1 + assert ( + job.initial_backoff * 0.8 <= job.delay() <= job.initial_backoff * 1.2 + ) + + job.attempt = 2 + assert ( + 2 * job.initial_backoff * 0.8 + <= job.delay() + <= 2 * job.initial_backoff * 1.2 + ) + + job.attempt = 3 + assert ( + (2**2) * job.initial_backoff * 0.8 + <= job.delay() + <= (2**2) * job.initial_backoff * 1.2 + ) + + +def test_job_delay_has_jitter(): + job = Job(payload="payload") + job.attempt = 1 + assert len({job.delay() for i in range(10)}) > 1 diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_client.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_client.py new file mode 100644 index 00000000000..f67c1808933 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_client.py @@ -0,0 +1,446 @@ +# 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. + +# pylint: disable=no-name-in-module + +import json +from unittest import mock + +import pytest + +from opentelemetry._opamp import messages +from opentelemetry._opamp.client import _HANDLED_CAPABILITIES, OpAMPClient +from opentelemetry._opamp.exceptions import ( + OpAMPRemoteConfigDecodeException, + OpAMPRemoteConfigParseException, +) +from opentelemetry._opamp.proto import opamp_pb2 +from opentelemetry._opamp.proto.anyvalue_pb2 import ( + AnyValue as PB2AnyValue, +) +from opentelemetry._opamp.proto.anyvalue_pb2 import ( + KeyValue as PB2KeyValue, +) +from opentelemetry._opamp.transport.requests import RequestsTransport +from opentelemetry._opamp.version import __version__ + + +@pytest.fixture(name="client") +def client_fixture(): + return OpAMPClient( + endpoint="url", agent_identifying_attributes={"foo": "bar"} + ) + + +def test_can_instantiate_opamp_client_with_defaults(): + client = OpAMPClient( + endpoint="url", agent_identifying_attributes={"foo": "bar"} + ) + + assert client + assert client._headers == { + "Content-Type": "application/x-protobuf", + "User-Agent": "OTel-OpAMP-Python/" + __version__, + } + assert client._tls_certificate is True + assert client._tls_client_certificate is None + assert client._tls_client_key is None + assert client._timeout_millis == 1_000 + assert client._sequence_num == 0 + assert isinstance(client._instance_uid, bytes) + assert isinstance(client._agent_description, opamp_pb2.AgentDescription) + assert client._agent_description.identifying_attributes == [ + PB2KeyValue(key="foo", value=PB2AnyValue(string_value="bar")), + ] + assert client._agent_description.non_identifying_attributes == [] + + +def test_can_instantiate_opamp_client_all_params(): + transport = RequestsTransport() + client = OpAMPClient( + endpoint="url", + headers={"an": "header"}, + timeout_millis=2_000, + agent_identifying_attributes={"foo": "bar"}, + agent_non_identifying_attributes={"bar": "baz"}, + transport=transport, + tls_certificate="ca.pem", + tls_client_certificate="client.pem", + tls_client_key="client-key.pem", + ) + + assert client + assert client._headers == { + "Content-Type": "application/x-protobuf", + "User-Agent": "OTel-OpAMP-Python/" + __version__, + "an": "header", + } + assert client._tls_certificate == "ca.pem" + assert client._tls_client_certificate == "client.pem" + assert client._tls_client_key == "client-key.pem" + assert client._timeout_millis == 2_000 + assert client._sequence_num == 0 + assert isinstance(client._instance_uid, bytes) + assert isinstance(client._agent_description, opamp_pb2.AgentDescription) + assert client._agent_description.identifying_attributes == [ + PB2KeyValue(key="foo", value=PB2AnyValue(string_value="bar")), + ] + assert client._agent_description.non_identifying_attributes == [ + PB2KeyValue(key="bar", value=PB2AnyValue(string_value="baz")), + ] + assert client._transport is transport + + +def test_client_headers_override_defaults(): + client = OpAMPClient( + endpoint="url", + agent_identifying_attributes={"foo": "bar"}, + headers={"User-Agent": "Custom"}, + ) + client._transport = mock.Mock() + client.send(b"") + + (send_call,) = client._transport.mock_calls + assert send_call == mock.call.send( + url="url", + headers={ + "Content-Type": "application/x-protobuf", + "User-Agent": "Custom", + }, + data=b"", + timeout_millis=1000, + tls_certificate=True, + tls_client_certificate=None, + tls_client_key=None, + ) + + +def test_can_serialize_agent_identifying_attributes(): + client = OpAMPClient( + endpoint="url", + agent_identifying_attributes={ + "string": "s", + "bytes": b"b", + "none": None, + "bool": True, + "int": 1, + "float": 2.0, + }, + ) + data = client.build_full_state_message() + + message = opamp_pb2.AgentToServer() + message.ParseFromString(data) + + assert message + assert message.instance_uid == client._instance_uid + assert message.sequence_num == 0 + assert message.agent_description.identifying_attributes == [ + PB2KeyValue(key="string", value=PB2AnyValue(string_value="s")), + PB2KeyValue(key="bytes", value=PB2AnyValue(bytes_value=b"b")), + PB2KeyValue(key="none", value=PB2AnyValue()), + PB2KeyValue(key="bool", value=PB2AnyValue(bool_value=True)), + PB2KeyValue(key="int", value=PB2AnyValue(int_value=1)), + PB2KeyValue(key="float", value=PB2AnyValue(double_value=2.0)), + ] + assert message.agent_description.non_identifying_attributes == [] + assert message.capabilities == _HANDLED_CAPABILITIES + + +def test_build_agent_disconnect_message(client): + data = client.build_agent_disconnect_message() + + message = opamp_pb2.AgentToServer() + message.ParseFromString(data) + + assert message + assert message.instance_uid == client._instance_uid + assert message.sequence_num == 0 + assert message.agent_disconnect == opamp_pb2.AgentDisconnect() + assert message.capabilities == _HANDLED_CAPABILITIES + + +def test_build_heartbeat_message(client): + data = client.build_heartbeat_message() + + message = opamp_pb2.AgentToServer() + message.ParseFromString(data) + + assert message + assert message.instance_uid == client._instance_uid + assert message.sequence_num == 0 + assert message.capabilities == _HANDLED_CAPABILITIES + + +def test_update_remote_config_status_without_previous_config(client): + remote_config_status = client.update_remote_config_status( + remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_APPLIED, + ) + + assert remote_config_status is not None + assert remote_config_status.last_remote_config_hash == b"12345678" + assert ( + remote_config_status.status == opamp_pb2.RemoteConfigStatuses_APPLIED + ) + assert remote_config_status.error_message == "" + + +def test_update_remote_config_status_with_same_config(client): + remote_config_status = client.update_remote_config_status( + remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_APPLIED, + ) + + assert remote_config_status is not None + + remote_config_status = client.update_remote_config_status( + remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_APPLIED, + ) + + assert remote_config_status is None + + +def test_update_remote_config_status_with_diffent_config(client): + remote_config_status = client.update_remote_config_status( + remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_APPLIED, + ) + + assert remote_config_status is not None + + # different status + remote_config_status = client.update_remote_config_status( + remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_FAILED, + ) + + assert remote_config_status is not None + + # different error message + remote_config_status = client.update_remote_config_status( + remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_FAILED, + error_message="different error message", + ) + + assert remote_config_status is not None + + # different hash + remote_config_status = client.update_remote_config_status( + remote_config_hash=b"1234", + status=opamp_pb2.RemoteConfigStatuses_FAILED, + error_message="different error message", + ) + + assert remote_config_status is not None + + +def test_build_remote_config_status_response_message_no_error_message(client): + remote_config_status = messages.build_remote_config_status_message( + last_remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_APPLIED, + ) + data = client.build_remote_config_status_response_message( + remote_config_status + ) + + message = opamp_pb2.AgentToServer() + message.ParseFromString(data) + + assert message + assert message.instance_uid == client._instance_uid + assert message.sequence_num == 0 + assert message.capabilities == _HANDLED_CAPABILITIES + assert message.remote_config_status + assert message.remote_config_status.last_remote_config_hash == b"12345678" + assert ( + message.remote_config_status.status + == opamp_pb2.RemoteConfigStatuses_APPLIED + ) + assert not message.remote_config_status.error_message + + +def test_build_remote_config_status_response_message_with_error_message( + client, +): + remote_config_status = messages.build_remote_config_status_message( + last_remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_FAILED, + error_message="an error message", + ) + data = client.build_remote_config_status_response_message( + remote_config_status + ) + + message = opamp_pb2.AgentToServer() + message.ParseFromString(data) + + assert message + assert message.instance_uid == client._instance_uid + assert message.sequence_num == 0 + assert message.capabilities == _HANDLED_CAPABILITIES + assert message.remote_config_status + assert message.remote_config_status.last_remote_config_hash == b"12345678" + assert ( + message.remote_config_status.status + == opamp_pb2.RemoteConfigStatuses_FAILED + ) + assert message.remote_config_status.error_message == "an error message" + + +def test_update_effective_config_json_content_type(client): + config = {"filename": {"a": "config"}} + client.update_effective_config(config, content_type="application/json") + + assert isinstance(client._effective_config, opamp_pb2.EffectiveConfig) + + decoded_config = {} + for ( + file_name, + config_file, + ) in client._effective_config.config_map.config_map.items(): + body = config_file.body.decode() + decoded_config[file_name] = json.loads(body) + + assert config == decoded_config + + +def test_build_full_state_message(client): + client.update_remote_config_status( + remote_config_hash=b"12345678", + status=opamp_pb2.RemoteConfigStatuses_APPLIED, + ) + config = {"filename": {"a": "config"}} + client.update_effective_config(config, content_type="application/json") + + data = client.build_full_state_message() + + message = opamp_pb2.AgentToServer() + message.ParseFromString(data) + + assert message + assert message.instance_uid == client._instance_uid + assert message.sequence_num == 0 + assert message.capabilities == _HANDLED_CAPABILITIES + assert message.agent_description.identifying_attributes == [ + PB2KeyValue(key="foo", value=PB2AnyValue(string_value="bar")), + ] + assert message.remote_config_status + assert message.remote_config_status.last_remote_config_hash == b"12345678" + assert ( + message.remote_config_status.status + == opamp_pb2.RemoteConfigStatuses_APPLIED + ) + assert "filename" in message.effective_config.config_map.config_map + config_file = message.effective_config.config_map.config_map["filename"] + assert config_file.content_type == "application/json" + body = config_file.body.decode() + assert config["filename"] == json.loads(body) + + +def test_build_full_state_message_no_config(client): + data = client.build_full_state_message() + + message = opamp_pb2.AgentToServer() + message.ParseFromString(data) + + assert message + assert message.instance_uid == client._instance_uid + assert message.sequence_num == 0 + assert message.capabilities == _HANDLED_CAPABILITIES + assert message.agent_description.identifying_attributes == [ + PB2KeyValue(key="foo", value=PB2AnyValue(string_value="bar")), + ] + assert message.remote_config_status + assert message.remote_config_status.last_remote_config_hash == b"" + assert ( + message.remote_config_status.status + == opamp_pb2.RemoteConfigStatuses_UNSET + ) + assert message.effective_config.config_map.config_map == {} + + +def test_message_sequence_num_increases_in_send(client): + client._transport = mock.Mock() + for index in range(2): + data = client.build_heartbeat_message() + client.send(data) + + message = opamp_pb2.AgentToServer() + message.ParseFromString(data) + + assert message + assert message.sequence_num == index + + +def test_send(client): + client._transport = mock.Mock() + client.send(b"foo") + + (send_call,) = client._transport.mock_calls + assert send_call == mock.call.send( + url="url", + headers={ + "Content-Type": "application/x-protobuf", + "User-Agent": "OTel-OpAMP-Python/" + __version__, + }, + data=b"foo", + timeout_millis=1000, + tls_certificate=True, + tls_client_certificate=None, + tls_client_key=None, + ) + + +def test_decode_remote_config(client): + config = opamp_pb2.AgentConfigMap() + config.config_map["application/json"].body = json.dumps( + {"a": "config"} + ).encode() + config.config_map["application/json"].content_type = "application/json" + config.config_map["text/json"].body = json.dumps( + {"other": "config"} + ).encode() + config.config_map["text/json"].content_type = "text/json" + message = opamp_pb2.AgentRemoteConfig(config=config) + + decoded = list(client.decode_remote_config(message)) + assert sorted(decoded) == sorted( + [ + ("application/json", {"a": "config"}), + ("text/json", {"other": "config"}), + ] + ) + + +def test_decode_remote_config_invalid_content_type(client): + config = opamp_pb2.AgentConfigMap() + config.config_map["filename"].body = b"1" + config.config_map["filename"].content_type = "not/json" + message = opamp_pb2.AgentRemoteConfig(config=config) + + with pytest.raises(OpAMPRemoteConfigParseException): + list(client.decode_remote_config(message)) + + +def test_decode_remote_config_invalid_file_body(client): + config = opamp_pb2.AgentConfigMap() + config.config_map["filename"].body = b"notjson" + config.config_map["filename"].content_type = "application/json" + message = opamp_pb2.AgentRemoteConfig(config=config) + + with pytest.raises(OpAMPRemoteConfigDecodeException): + list(client.decode_remote_config(message)) diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py new file mode 100644 index 00000000000..68ceec414b9 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py @@ -0,0 +1,117 @@ +# 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. + +import logging +import sys +from time import sleep +from unittest import mock + +import pytest + +from opentelemetry._opamp.agent import OpAMPAgent +from opentelemetry._opamp.client import OpAMPClient +from opentelemetry._opamp.proto import opamp_pb2 + + +@pytest.mark.skipif( + sys.version_info < (3, 10), + reason="vcr.py not working with urllib 2 and older Pythons", +) +@pytest.mark.vcr() +def test_connection_remote_config_status_heartbeat_disconnection(caplog): + caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") + + def opamp_handler(agent, client, message): + logger = logging.getLogger("opentelemetry._opamp.agent.opamp_handler") + + logger.debug("In opamp_handler") + + # we need to update the config only if we have a config + if not message.remote_config.config_hash: + return + + updated_remote_config = client.update_remote_config_status( + remote_config_hash=message.remote_config.config_hash, + status=opamp_pb2.RemoteConfigStatuses_APPLIED, + error_message="", + ) + if updated_remote_config is not None: + logger.debug("Updated Remote Config") + message = client.build_remote_config_status_response_message( + updated_remote_config + ) + agent.send(payload=message) + + opamp_client = OpAMPClient( + endpoint="https://localhost:4320/v1/opamp", + agent_identifying_attributes={ + "service.name": "foo", + "deployment.environment.name": "foo", + }, + tls_certificate=False, + ) + opamp_agent = OpAMPAgent( + interval=1, + message_handler=opamp_handler, + client=opamp_client, + ) + opamp_agent.start() + + # this should be enough for the heartbeat message to be sent + sleep(1.5) + + opamp_agent.stop() + + handler_records = [ + record[2] + for record in caplog.record_tuples + if record[0] == "opentelemetry._opamp.agent.opamp_handler" + ] + # one call is for connection, one is remote config status, one is heartbeat + assert handler_records == [ + "In opamp_handler", + "Updated Remote Config", + "In opamp_handler", + "In opamp_handler", + ] + + +@pytest.mark.skipif( + sys.version_info < (3, 10), + reason="vcr.py not working with urllib 2 and older Pythons", +) +@pytest.mark.vcr() +def test_with_server_not_responding(caplog): + caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") + + opamp_handler = mock.Mock() + + opamp_client = OpAMPClient( + endpoint="https://localhost:4399/v1/opamp", + agent_identifying_attributes={ + "service.name": "foo", + "deployment.environment.name": "foo", + }, + tls_certificate=False, + ) + opamp_agent = OpAMPAgent( + interval=1, + message_handler=opamp_handler, + client=opamp_client, + ) + opamp_agent.start() + + opamp_agent.stop() + + assert opamp_handler.call_count == 0 diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/transport/test_requests.py b/opamp/opentelemetry-opamp-client/tests/opamp/transport/test_requests.py new file mode 100644 index 00000000000..ff462554ca7 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/tests/opamp/transport/test_requests.py @@ -0,0 +1,178 @@ +# 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 unittest import mock + +import pytest +import requests + +from opentelemetry._opamp.proto import opamp_pb2 +from opentelemetry._opamp.transport.base import base_headers +from opentelemetry._opamp.transport.exceptions import OpAMPException +from opentelemetry._opamp.transport.requests import RequestsTransport + + +def test_can_instantiate_requests_transport(): + transport = RequestsTransport() + + assert transport + + +def test_can_instantiate_requests_transport_with_own_session(): + session = requests.Session() + transport = RequestsTransport(session=session) + + assert transport + assert transport.session is session + + +def test_can_send(): + transport = RequestsTransport() + serialized_message = opamp_pb2.ServerToAgent().SerializeToString() + response_mock = mock.Mock(content=serialized_message) + headers = {"foo": "bar"} + expected_headers = {**base_headers, **headers} + data = b"" + with mock.patch.object(transport, "session") as session_mock: + session_mock.post.return_value = response_mock + response = transport.send( + url="http://127.0.0.1/v1/opamp", + headers=headers, + data=data, + timeout_millis=1_000, + tls_certificate=True, + ) + + session_mock.post.assert_called_once_with( + "http://127.0.0.1/v1/opamp", + headers=expected_headers, + data=data, + timeout=1, + verify=True, + cert=None, + ) + + assert isinstance(response, opamp_pb2.ServerToAgent) + + +def test_send_tls_certificate_mapped_to_verify(): + transport = RequestsTransport() + serialized_message = opamp_pb2.ServerToAgent().SerializeToString() + response_mock = mock.Mock(content=serialized_message) + data = b"" + with mock.patch.object(transport, "session") as session_mock: + session_mock.post.return_value = response_mock + response = transport.send( + url="https://127.0.0.1/v1/opamp", + headers={}, + data=data, + timeout_millis=1_000, + tls_certificate=False, + ) + + session_mock.post.assert_called_once_with( + "https://127.0.0.1/v1/opamp", + headers=base_headers, + data=data, + timeout=1, + verify=False, + cert=None, + ) + + assert isinstance(response, opamp_pb2.ServerToAgent) + + +def test_send_mtls(): + transport = RequestsTransport() + serialized_message = opamp_pb2.ServerToAgent().SerializeToString() + response_mock = mock.Mock(content=serialized_message) + data = b"" + with mock.patch.object(transport, "session") as session_mock: + session_mock.post.return_value = response_mock + response = transport.send( + url="https://127.0.0.1/v1/opamp", + headers={}, + data=data, + timeout_millis=1_000, + tls_certificate="server.pem", + tls_client_certificate="client.pem", + tls_client_key="client.key", + ) + + session_mock.post.assert_called_once_with( + "https://127.0.0.1/v1/opamp", + headers=base_headers, + data=data, + timeout=1, + verify="server.pem", + cert=("client.pem", "client.key"), + ) + + assert isinstance(response, opamp_pb2.ServerToAgent) + + +def test_send_mtls_no_client_key(): + transport = RequestsTransport() + serialized_message = opamp_pb2.ServerToAgent().SerializeToString() + response_mock = mock.Mock(content=serialized_message) + data = b"" + with mock.patch.object(transport, "session") as session_mock: + session_mock.post.return_value = response_mock + response = transport.send( + url="https://127.0.0.1/v1/opamp", + headers={}, + data=data, + timeout_millis=1_000, + tls_certificate="server.pem", + tls_client_certificate="client.pem", + ) + + session_mock.post.assert_called_once_with( + "https://127.0.0.1/v1/opamp", + headers=base_headers, + data=data, + timeout=1, + verify="server.pem", + cert="client.pem", + ) + + assert isinstance(response, opamp_pb2.ServerToAgent) + + +def test_send_exceptions_raises_opamp_exception(): + transport = RequestsTransport() + response_mock = mock.Mock() + headers = {"foo": "bar"} + expected_headers = {**base_headers, **headers} + data = b"" + with mock.patch.object(transport, "session") as session_mock: + session_mock.post.return_value = response_mock + response_mock.raise_for_status.side_effect = Exception + with pytest.raises(OpAMPException): + transport.send( + url="http://127.0.0.1/v1/opamp", + headers=headers, + data=data, + timeout_millis=1_000, + tls_certificate=True, + ) + + session_mock.post.assert_called_once_with( + "http://127.0.0.1/v1/opamp", + headers=expected_headers, + data=data, + timeout=1, + verify=True, + cert=None, + ) diff --git a/pyproject.toml b/pyproject.toml index 99ba8d2e321..7e6b2c85258 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -209,6 +209,7 @@ include = [ "util/opentelemetry-util-genai", "exporter/opentelemetry-exporter-credential-provider-gcp", "instrumentation/opentelemetry-instrumentation-aiohttp-client", + "opamp/opentelemetry-opamp-client", ] # We should also add type hints to the test suite - It helps on finding bugs. # We are excluding for now because it's easier, and more important to add to the instrumentation packages. @@ -228,6 +229,8 @@ exclude = [ "instrumentation-genai/opentelemetry-instrumentation-weaviate/examples/**/*.py", "util/opentelemetry-util-genai/tests/**/*.py", "instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/**/*.py", + "opamp/opentelemetry-opamp-client/tests/**/*.py", + "opamp/opentelemetry-opamp-client/src/opentelemetry/**/proto/**", ] [dependency-groups] diff --git a/scripts/build.sh b/scripts/build.sh index c652e399b62..fd5a207cae5 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -16,7 +16,7 @@ DISTDIR=dist mkdir -p $DISTDIR rm -rf ${DISTDIR:?}/* - for d in exporter/*/ opentelemetry-instrumentation/ opentelemetry-contrib-instrumentations/ opentelemetry-distro/ instrumentation/*/ processor/*/ propagator/*/ resource/*/ sdk-extension/*/ util/*/ ; do + for d in exporter/*/ opentelemetry-instrumentation/ opentelemetry-contrib-instrumentations/ opentelemetry-distro/ instrumentation/*/ processor/*/ propagator/*/ resource/*/ sdk-extension/*/ util/*/ opamp/*/ ; do ( echo "building $d" cd "$d" diff --git a/scripts/opamp_proto_codegen.sh b/scripts/opamp_proto_codegen.sh new file mode 100755 index 00000000000..23db6e354f1 --- /dev/null +++ b/scripts/opamp_proto_codegen.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# 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. + +# Regenerate python code from opamp protos in +# https://github.com/open-telemetry/opamp-spec +# +# To use, update OPAMP_SPEC_REPO_BRANCH_OR_COMMIT variable below to a commit hash or +# tag in opentelemtry-proto repo that you want to build off of. Then, just run +# this script to update the proto files. Commit the changes as well as any +# fixes needed in the OTLP exporter. +# +# Optional envars: +# OPAMP_SPEC_REPO_DIR - the path to an existing checkout of the opamp-spec repo + +# Pinned commit/branch/tag for the current version used in the opamp python package. +OPAMP_SPEC_REPO_BRANCH_OR_COMMIT="v0.12.0" + +set -e + +OPAMP_SPEC_REPO_DIR=${OPAMP_SPEC_REPO_DIR:-"/tmp/opamp-spec"} +# root of opentelemetry-python repo +repo_root="$(git rev-parse --show-toplevel)" +proto_output_dir="$repo_root/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/proto" + +protoc() { + uvx -c $repo_root/opamp-gen-requirements.txt \ + --python 3.12 \ + --from grpcio-tools \ + --with mypy-protobuf \ + python -m grpc_tools.protoc "$@" +} + +protoc --version + +# Clone the proto repo if it doesn't exist +if [ ! -d "$OPAMP_SPEC_REPO_DIR" ]; then + git clone https://github.com/open-telemetry/opamp-spec.git $OPAMP_SPEC_REPO_DIR +fi + +# Pull in changes and switch to requested branch +( + cd $OPAMP_SPEC_REPO_DIR + git fetch --all + git checkout $OPAMP_SPEC_REPO_BRANCH_OR_COMMIT + # pull if OPAMP_SPEC_BRANCH_OR_COMMIT is not a detached head + git symbolic-ref -q HEAD && git pull --ff-only || true +) + +cd $proto_output_dir + +# clean up old generated code +find . -regex ".*_pb2.*\.pyi?" -exec rm {} + + +# generate proto code for all protos +all_protos=$(find $OPAMP_SPEC_REPO_DIR/ -name "*.proto") +protoc \ + -I $OPAMP_SPEC_REPO_DIR/proto \ + --python_out=. \ + --mypy_out=. \ + $all_protos + +sed -i -e 's/import anyvalue_pb2 as anyvalue__pb2/from . import anyvalue_pb2 as anyvalue__pb2/' opamp_pb2.py diff --git a/tox.ini b/tox.ini index 350584e85a2..2bf938d4412 100644 --- a/tox.ini +++ b/tox.ini @@ -447,6 +447,12 @@ envlist = ; requires snappy headers to be available on the system lint-processor-baggage + ; opentelemetry-opamp-client + py3{9,10,11,12,13,14}-test-opamp-client-{latest,lowest} + ; https://github.com/kevin1024/vcrpy/pull/775#issuecomment-1847849962 + ; pypy3-test-opamp-client + lint-opamp-client + spellcheck docker-tests docs @@ -758,6 +764,11 @@ deps = processor-baggage: {[testenv]test_deps} processor-baggage: -r {toxinidir}/processor/opentelemetry-processor-baggage/test-requirements.txt + opamp-client: {[testenv]test_deps} + opamp-client-lowest: -r {toxinidir}/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt + opamp-client-latest: -r {toxinidir}/opamp/opentelemetry-opamp-client/test-requirements.latest.txt + lint-opamp-client: -r {toxinidir}/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt + util-http: {[testenv]test_deps} util-http: -r {toxinidir}/util/opentelemetry-util-http/test-requirements.txt util-http: {toxinidir}/util/opentelemetry-util-http @@ -1007,6 +1018,9 @@ commands = test-exporter-prometheus-remote-write: pytest {toxinidir}/exporter/opentelemetry-exporter-prometheus-remote-write/tests {posargs} lint-exporter-prometheus-remote-write: sh -c "cd exporter && pylint --rcfile ../.pylintrc opentelemetry-exporter-prometheus-remote-write" + test-opamp-client: pytest {toxinidir}/opamp/opentelemetry-opamp-client/tests {posargs} + lint-opamp-client: sh -c "cd opamp && pylint --rcfile ../.pylintrc opentelemetry-opamp-client" + coverage: {toxinidir}/scripts/coverage.sh [testenv:docs] @@ -1122,6 +1136,7 @@ commands = deps = -c {toxinidir}/dev-requirements.txt pyright + protobuf==6.31.1 {[testenv]test_deps} {toxinidir}/opentelemetry-instrumentation {toxinidir}/util/opentelemetry-util-http @@ -1135,6 +1150,7 @@ deps = {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncclick[instruments] {toxinidir}/exporter/opentelemetry-exporter-credential-provider-gcp {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client[instruments] + {toxinidir}/opamp/opentelemetry-opamp-client commands = pyright From d7a3b18760821854bb3dd3affb938758ab560cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 6 Mar 2026 07:48:51 -0300 Subject: [PATCH 02/78] fix fastapi tests failure with >= 0.118.0 (#4277) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .../test-requirements.txt | 6 +++--- .../tests/test_fastapi_instrumentation.py | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt index 6c67a9f7caa..09e4a15c5e7 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-fastapi/test-requirements.txt @@ -1,18 +1,18 @@ annotated-types==0.7.0 -anyio==4.3.0 +anyio==4.12.1 asgiref==3.8.1 certifi==2024.7.4 charset-normalizer==3.3.2 Deprecated==1.2.14 exceptiongroup==1.2.0 -fastapi==0.117.0 +fastapi==0.126.0 h11==0.16.0 httpcore==1.0.9 httpx==0.28.1 idna==3.7 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pydantic==2.12.5 pydantic_core==2.41.5 diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 21275366e2c..a2a8fb47750 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -25,6 +25,7 @@ import fastapi import pytest +from fastapi.middleware.asyncexitstack import AsyncExitStackMiddleware from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware from fastapi.responses import JSONResponse, PlainTextResponse from fastapi.routing import APIRoute @@ -2073,7 +2074,12 @@ def _create_fastapi_app(): app = TestBaseFastAPI._create_fastapi_app() def build_middleware_stack(): - return app.router + # Return something that is NOT a ServerErrorMiddleware so the + # instrumentation fallback path triggers, but still wrap the + # router with AsyncExitStackMiddleware so that newer FastAPI + # versions (which assert ``fastapi_middleware_astack`` exists in + # the request scope) can service requests normally. + return AsyncExitStackMiddleware(app.router) app.build_middleware_stack = build_middleware_stack return app @@ -2098,7 +2104,7 @@ def test_no_instrumentation(self): self.assertEqual(len(errors), 1) self.assertEqual( errors[0].getMessage(), - "Skipping FastAPI instrumentation due to unexpected middleware stack: expected ServerErrorMiddleware, got ", + "Skipping FastAPI instrumentation due to unexpected middleware stack: expected ServerErrorMiddleware, got ", ) From 7701174242ebca38e7ba04169af2c770d0aa6849 Mon Sep 17 00:00:00 2001 From: Mike Goldsmith Date: Fri, 6 Mar 2026 20:14:30 +0000 Subject: [PATCH 03/78] fix(ci): eliminate SHA propagation flakiness in Core Contrib Test (#4305) * fix(ci): eliminate SHA propagation flakiness in Core Contrib Test Each Core Contrib Test job was doing two separate git operations for the core repo: actions/checkout (uses GitHub internal API, always works) and then tox installing packages via git+https:// (hits public CDN, fails when SHA hasn't propagated yet). Fix by setting per-package env vars (CORE_REPO_API, CORE_REPO_SDK, CORE_REPO_SEMCONV, CORE_REPO_TEST_UTILS) in the CI workflow to point at the already-checked-out local copy, eliminating the second network clone entirely. Backward compatible: when the new vars are unset (local dev), they fall back to the existing git URL + subdirectory behavior. Fixes #4304 Assisted-by: Claude Sonnet 4.6 * fix: restore version header dropped during rebase Assisted-by: Claude Sonnet 4.6 * move CORE_REPO_* vars to top-level env block Use github.workspace context instead of a shell step to set the per-package local path env vars, as suggested in code review. Assisted-by: Claude Sonnet 4.6 --- .github/workflows/core_contrib_test_0.yml | 4 ++++ .../generate_workflows_lib/core_contrib_test.yml.j2 | 4 ++++ CHANGELOG.md | 5 +++++ tox.ini | 12 ++++++++---- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index d6950358ad0..6cc751461a5 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -20,6 +20,10 @@ env: CORE_REPO_SHA: ${{ inputs.CORE_REPO_SHA }} CONTRIB_REPO_SHA: ${{ inputs.CONTRIB_REPO_SHA }} PIP_EXISTS_ACTION: w + CORE_REPO_API: ${{ github.workspace }}/opentelemetry-python/opentelemetry-api + CORE_REPO_SDK: ${{ github.workspace }}/opentelemetry-python/opentelemetry-sdk + CORE_REPO_SEMCONV: ${{ github.workspace }}/opentelemetry-python/opentelemetry-semantic-conventions + CORE_REPO_TEST_UTILS: ${{ github.workspace }}/opentelemetry-python/tests/opentelemetry-test-utils jobs: diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 index c8d2af59d09..5fce8e1cfe2 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 @@ -20,6 +20,10 @@ env: CORE_REPO_SHA: ${% raw %}{{ inputs.CORE_REPO_SHA }}{% endraw %} CONTRIB_REPO_SHA: ${% raw %}{{ inputs.CONTRIB_REPO_SHA }}{% endraw %} PIP_EXISTS_ACTION: w + CORE_REPO_API: ${% raw %}{{ github.workspace }}{% endraw %}/opentelemetry-python/opentelemetry-api + CORE_REPO_SDK: ${% raw %}{{ github.workspace }}{% endraw %}/opentelemetry-python/opentelemetry-sdk + CORE_REPO_SEMCONV: ${% raw %}{{ github.workspace }}{% endraw %}/opentelemetry-python/opentelemetry-semantic-conventions + CORE_REPO_TEST_UTILS: ${% raw %}{{ github.workspace }}{% endraw %}/opentelemetry-python/tests/opentelemetry-test-utils jobs: {%- for job_data in job_datas %} diff --git a/CHANGELOG.md b/CHANGELOG.md index 61e48270205..3e68eb2cd82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +- Fix intermittent `Core Contrib Test` CI failures caused by GitHub git CDN SHA propagation lag by installing core packages from the already-checked-out local copy instead of a second git clone + ([#4305](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4305)) + ## Version 1.40.0/0.61b0 (2026-03-04) ### Added diff --git a/tox.ini b/tox.ini index 2bf938d4412..0ce7d20b7fd 100644 --- a/tox.ini +++ b/tox.ini @@ -464,10 +464,10 @@ envlist = [testenv] test_deps = - opentelemetry-api@{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api - opentelemetry-semantic-conventions@{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions - opentelemetry-sdk@{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk - opentelemetry-test-utils@{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils + opentelemetry-api@{env:CORE_REPO_API} + opentelemetry-semantic-conventions@{env:CORE_REPO_SEMCONV} + opentelemetry-sdk@{env:CORE_REPO_SDK} + opentelemetry-test-utils@{env:CORE_REPO_TEST_UTILS} deps = lint: -r dev-requirements.txt coverage: pytest @@ -790,6 +790,10 @@ setenv = ; i.e: CORE_REPO_SHA=dde62cebffe519c35875af6d06fae053b3be65ec tox -e CORE_REPO_SHA={env:CORE_REPO_SHA:main} CORE_REPO=git+https://github.com/open-telemetry/opentelemetry-python.git@{env:CORE_REPO_SHA} + CORE_REPO_API={env:CORE_REPO_API:{env:CORE_REPO}\#egg=opentelemetry-api&subdirectory=opentelemetry-api} + CORE_REPO_SDK={env:CORE_REPO_SDK:{env:CORE_REPO}\#egg=opentelemetry-sdk&subdirectory=opentelemetry-sdk} + CORE_REPO_SEMCONV={env:CORE_REPO_SEMCONV:{env:CORE_REPO}\#egg=opentelemetry-semantic-conventions&subdirectory=opentelemetry-semantic-conventions} + CORE_REPO_TEST_UTILS={env:CORE_REPO_TEST_UTILS:{env:CORE_REPO}\#egg=opentelemetry-test-utils&subdirectory=tests/opentelemetry-test-utils} UV_CONFIG_FILE={toxinidir}/tox-uv.toml PIP_CONSTRAINTS={toxinidir}/test-constraints.txt UV_BUILD_CONSTRAINT={toxinidir}/test-constraints.txt From 03891c0aaa5ef7c05f6fd0946f70b930c4dad7ca Mon Sep 17 00:00:00 2001 From: Nagkumar Arkalgud Date: Fri, 6 Mar 2026 12:22:32 -0800 Subject: [PATCH 04/78] fix(openai-agents): align AgentSpanData stubs and span processor with real SDK (#4229) --- .../CHANGELOG.md | 3 ++ .../openai_agents/span_processor.py | 33 ++++++------------- .../tests/stubs/agents/tracing/__init__.py | 17 ++++++---- .../tests/test_tracer.py | 31 +++++++---------- .../tests/test_z_span_processor_unit.py | 31 +++++------------ 5 files changed, 43 insertions(+), 72 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md index 95f69d6dedf..550c74b9d03 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased +- Align AgentSpanData test stubs and span processor with real OpenAI Agents SDK; + remove non-existent `operation`, `description`, `agent_id`, and `model` fields. + ([#4229](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4229)) - Document official package metadata and README for the OpenAI Agents instrumentation. ([#3859](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3859)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py index d1dce8ec5e3..d8b28279edf 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py @@ -1519,17 +1519,8 @@ def _get_operation_name(self, span_data: Any) -> str: return GenAIOperationName.CHAT return GenAIOperationName.TEXT_COMPLETION if _is_instance_of(span_data, AgentSpanData): - # Could be create_agent or invoke_agent based on context - operation = getattr(span_data, "operation", None) - normalized = ( - operation.strip().lower() - if isinstance(operation, str) - else None - ) - if normalized in {"create", "create_agent"}: - return GenAIOperationName.CREATE_AGENT - if normalized in {"invoke", "invoke_agent"}: - return GenAIOperationName.INVOKE_AGENT + # The OpenAI Agents SDK AgentSpanData has no "operation" field; + # agent spans always represent invoke_agent. return GenAIOperationName.INVOKE_AGENT if _is_instance_of(span_data, FunctionSpanData): return GenAIOperationName.EXECUTE_TOOL @@ -1831,24 +1822,20 @@ def _get_attributes_from_agent_span_data( if name: yield GEN_AI_AGENT_NAME, name - agent_id = ( - self.agent_id - or getattr(span_data, "agent_id", None) - or self._agent_id_default - ) + # agent_id and description are not available on the OpenAI Agents SDK + # AgentSpanData; only use user-configured overrides. + agent_id = self.agent_id or self._agent_id_default if agent_id: yield GEN_AI_AGENT_ID, agent_id - description = ( - self.agent_description - or getattr(span_data, "description", None) - or self._agent_description_default - ) + description = self.agent_description or self._agent_description_default if description: yield GEN_AI_AGENT_DESCRIPTION, description - model = getattr(span_data, "model", None) - if not model and agent_content: + # The OpenAI Agents SDK AgentSpanData has no "model" field; fall back to + # the model aggregated from child generation/response spans. + model = None + if agent_content: model = agent_content.get("request_model") if model: yield GEN_AI_REQUEST_MODEL, model diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/stubs/agents/tracing/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/stubs/agents/tracing/__init__.py index 4ed06c89771..509fd537b35 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/stubs/agents/tracing/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/stubs/agents/tracing/__init__.py @@ -35,12 +35,9 @@ @dataclass class AgentSpanData: name: str | None = None + handoffs: list[str] | None = None tools: list[str] | None = None output_type: str | None = None - description: str | None = None - agent_id: str | None = None - model: str | None = None - operation: str | None = None @property def type(self) -> str: @@ -200,8 +197,16 @@ def generation_span(**kwargs: Any): @contextmanager -def agent_span(**kwargs: Any): - data = AgentSpanData(**kwargs) +def agent_span( + name: str, + handoffs: list[str] | None = None, + tools: list[str] | None = None, + output_type: str | None = None, + **kwargs: Any, +): + data = AgentSpanData( + name=name, handoffs=handoffs, tools=tools, output_type=output_type + ) span = _PROVIDER.create_span(data, parent=_CURRENT_TRACE) span.start() try: diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py index 1f21ab25c0c..a2e8143b0dd 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py @@ -171,40 +171,31 @@ def test_function_span_records_tool_attributes(): exporter.clear() -def test_agent_create_span_records_attributes(): +def test_agent_invoke_span_records_attributes(): instrumentor, exporter = _instrument_with_provider() try: with trace("workflow"): with agent_span( - operation="create", name="support_bot", - description="Answers support questions", - agent_id="agt_123", - model="gpt-4o-mini", + handoffs=["escalation_bot"], + tools=["search"], + output_type="str", ): pass spans = exporter.get_finished_spans() - create_span = next( + invoke_span = next( span for span in spans if span.attributes[GenAI.GEN_AI_OPERATION_NAME] - == GenAI.GenAiOperationNameValues.CREATE_AGENT.value + == GenAI.GenAiOperationNameValues.INVOKE_AGENT.value ) - assert create_span.kind is SpanKind.CLIENT - assert create_span.name == "create_agent support_bot" - assert create_span.attributes[GEN_AI_PROVIDER_NAME] == "openai" - assert create_span.attributes[GenAI.GEN_AI_AGENT_NAME] == "support_bot" - assert ( - create_span.attributes[GenAI.GEN_AI_AGENT_DESCRIPTION] - == "Answers support questions" - ) - assert create_span.attributes[GenAI.GEN_AI_AGENT_ID] == "agt_123" - assert ( - create_span.attributes[GenAI.GEN_AI_REQUEST_MODEL] == "gpt-4o-mini" - ) + assert invoke_span.kind is SpanKind.CLIENT + assert invoke_span.name == "invoke_agent support_bot" + assert invoke_span.attributes[GEN_AI_PROVIDER_NAME] == "openai" + assert invoke_span.attributes[GenAI.GEN_AI_AGENT_NAME] == "support_bot" finally: instrumentor.uninstrument() exporter.clear() @@ -425,7 +416,7 @@ def test_agent_name_override_applied_to_agent_spans(): try: with trace("workflow"): - with agent_span(operation="invoke", name="support_bot"): + with agent_span(name="support_bot"): pass spans = exporter.get_finished_spans() diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_z_span_processor_unit.py b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_z_span_processor_unit.py index b2c8c7c8f38..c879aa06a16 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_z_span_processor_unit.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_z_span_processor_unit.py @@ -156,19 +156,14 @@ def test_operation_and_span_naming(processor_setup): == sp.GenAIOperationName.EMBEDDINGS ) - agent_create = AgentSpanData(operation=" CREATE ") + # AgentSpanData always maps to invoke_agent (no operation field in OpenAI Agents SDK) + agent_data = AgentSpanData(name="bot") assert ( - processor._get_operation_name(agent_create) - == sp.GenAIOperationName.CREATE_AGENT - ) - - agent_invoke = AgentSpanData(operation="invoke_agent") - assert ( - processor._get_operation_name(agent_invoke) + processor._get_operation_name(agent_data) == sp.GenAIOperationName.INVOKE_AGENT ) - agent_default = AgentSpanData(operation=None) + agent_default = AgentSpanData() assert ( processor._get_operation_name(agent_default) == sp.GenAIOperationName.INVOKE_AGENT @@ -315,26 +310,19 @@ def __init__(self) -> None: agent_span = AgentSpanData( name="helper", output_type="json", - description="desc", - agent_id="agent-123", - model="model-x", - operation="invoke_agent", ) agent_attrs = _collect( processor._get_attributes_from_agent_span_data(agent_span, None) ) assert agent_attrs[sp.GEN_AI_AGENT_NAME] == "helper" - assert agent_attrs[sp.GEN_AI_AGENT_ID] == "agent-123" - assert agent_attrs[sp.GEN_AI_REQUEST_MODEL] == "model-x" + assert sp.GEN_AI_AGENT_ID not in agent_attrs + assert sp.GEN_AI_REQUEST_MODEL not in agent_attrs assert agent_attrs[sp.GEN_AI_OUTPUT_TYPE] == sp.GenAIOutputType.TEXT # Fallback to aggregated model when span data lacks it agent_span_no_model = AgentSpanData( name="helper-2", output_type="json", - description="desc", - agent_id="agent-456", - operation="invoke_agent", ) agent_content = { "input_messages": [], @@ -435,9 +423,7 @@ def test_span_lifecycle_and_shutdown(processor_setup): parent_span = FakeSpan( trace_id="trace-1", span_id="span-1", - span_data=AgentSpanData( - operation="invoke", name="agent", model="gpt-4o" - ), + span_data=AgentSpanData(name="agent"), started_at="2024-01-01T00:00:00Z", ended_at="2024-01-01T00:00:02Z", ) @@ -476,7 +462,7 @@ def test_span_lifecycle_and_shutdown(processor_setup): linger_span = FakeSpan( trace_id="trace-2", span_id="span-3", - span_data=AgentSpanData(operation=None), + span_data=AgentSpanData(), started_at="2024-01-01T00:00:06Z", ) processor.on_span_start(linger_span) @@ -518,7 +504,6 @@ def test_chat_span_renamed_with_model(processor_setup): trace_id=trace.trace_id, span_id="agent-span", span_data=AgentSpanData( - operation="invoke_agent", name="Agent", ), started_at="2025-01-01T00:00:00Z", From 578373a91fb44113638fe658abc66bb5d954333c Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 9 Mar 2026 10:56:46 +0100 Subject: [PATCH 05/78] Cleanup docker tests (#4311) * Remove unneded packages from docker tests * Bump some dependencies to avoid warning on deprecated crypto algos * Remove instrumentations that are not tested in docker-tests --- .../tests/test-requirements.txt | 16 ++++++---------- tox.ini | 6 ------ 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/tests/opentelemetry-docker-tests/tests/test-requirements.txt b/tests/opentelemetry-docker-tests/tests/test-requirements.txt index 048d35cb4c4..8bac6ab055e 100644 --- a/tests/opentelemetry-docker-tests/tests/test-requirements.txt +++ b/tests/opentelemetry-docker-tests/tests/test-requirements.txt @@ -4,18 +4,17 @@ asgiref==3.8.1 async-timeout==4.0.3 asyncpg==0.29.0 attrs==23.2.0 -bcrypt==4.1.2 +bcrypt==5.0.0 billiard==4.2.0 celery==5.3.6 certifi==2024.7.4 -cffi==1.16.0 +cffi==2.0.0 chardet==3.0.4 click==8.1.7 click-didyoumean==0.3.0 click-plugins==1.1.1 click-repl==0.3.0 -cryptography==44.0.1 -Deprecated==1.2.14 +cryptography==45.0.7 distro==1.9.0 Django==4.2.17 dnspython==2.6.1 @@ -34,23 +33,21 @@ jsonschema==3.2.0 kombu==5.3.5 mysql-connector-python==8.3.0 mysqlclient==2.1.1 -opencensus-proto==0.1.0 packaging==24.0 -paramiko==3.4.0 +paramiko==4.0.0 pluggy==1.4.0 prometheus_client==0.20.0 prompt-toolkit==3.0.43 -protobuf==3.20.3 # prerequisite: install libpq-dev (debian) or postgresql-devel (rhel), postgresql (mac) # see https://www.psycopg.org/docs/install.html#build-prerequisites # you might have to install additional packages depending on your OS psycopg==3.1.18 psycopg2==2.9.9 psycopg2-binary==2.9.9 -pycparser==2.21 +pycparser==3.0 pymongo==4.6.3 PyMySQL==0.10.1 -PyNaCl==1.5.0 +PyNaCl==1.6.2 # prerequisite: install unixodbc pyodbc==5.0.1 pyrsistent==0.20.0 @@ -61,7 +58,6 @@ python-dotenv==0.21.1 pytz==2024.1 PyYAML==5.3.1 redis==5.0.1 -remoulade==3.2.0 requests==2.25.0 six==1.16.0 SQLAlchemy==1.4.52 diff --git a/tox.ini b/tox.ini index 0ce7d20b7fd..7a21521de08 100644 --- a/tox.ini +++ b/tox.ini @@ -1060,10 +1060,6 @@ deps = -e {toxinidir}/opentelemetry-instrumentation -e {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg -e {toxinidir}/instrumentation/opentelemetry-instrumentation-celery - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-pika - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aiokafka - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-kafka-python - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka -e {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi -e {toxinidir}/instrumentation/opentelemetry-instrumentation-django -e {toxinidir}/instrumentation/opentelemetry-instrumentation-flask @@ -1077,10 +1073,8 @@ deps = -e {toxinidir}/instrumentation/opentelemetry-instrumentation-sqlalchemy -e {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg -e {toxinidir}/instrumentation/opentelemetry-instrumentation-redis - -e {toxinidir}/instrumentation/opentelemetry-instrumentation-remoulade -e {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi -e {toxinidir}/util/opentelemetry-util-http - opentelemetry-exporter-opencensus@{env:CORE_REPO}\#egg=opentelemetry-exporter-opencensus&subdirectory=exporter/opentelemetry-exporter-opencensus changedir = tests/opentelemetry-docker-tests/tests From ff7f60ef80c8a72d235309c6a4f6a603397f9ae5 Mon Sep 17 00:00:00 2001 From: Teja Date: Mon, 9 Mar 2026 10:34:04 -0400 Subject: [PATCH 06/78] feat: Add sync streaming support for Anthropic instrumentation (#4155) * Add sync streaming support for Anthropic instrumentation - Add support for Messages.create(stream=True) with StreamWrapper - Add support for Messages.stream() with MessageStreamManagerWrapper - Add MessageWrapper for non-streaming response telemetry - Rename MessageCreateParams to MessageRequestParams - Add comprehensive tests for sync streaming functionality * Add changelog entry for sync streaming support * Fix type checking errors with type: ignore comments - Add type: ignore[arg-type] for Union type narrowing in messages_create - Add type: ignore[return-value] for wrapper return types - Add type: ignore[return-value] for __exit__ returning None * Refactor Anthropic instrumentation to improve usage tracking and error handling - Introduce constants for provider name and cache token attributes. - Normalize stop reasons and aggregate cache token fields in MessageWrapper and StreamWrapper. - Enhance tests to validate input token aggregation and stop reason normalization. - Update cassettes for new request and response structures in streaming scenarios. * Refactor utility functions and test cases for improved readability and consistency - Simplify constant definitions and normalize function calls in utils.py. - Enhance test cases by removing unnecessary line breaks and improving formatting. - Ensure consistent usage of type hints and comments in test functions. * Refactor argument handling in assert_span_attributes function - Update the pylint directive to disable too-many-arguments warning for better clarity. - Maintain consistency in function signature and improve code readability. * Enhance tests for streaming message handling in Anthropic instrumentation - Update test cases to validate streaming behavior with various parameters, including token usage and stop reasons. - Introduce new cassettes for different scenarios, ensuring comprehensive coverage of streaming interactions. - Refactor existing tests for clarity and consistency in structure and assertions. * Update test_sync_messages.py to disable pylint warning for too-many-locals in test_stream_wrapper_finalize_idempotent function * Enhance StreamWrapper and MessageStreamManagerWrapper for idempotent finalization - Refactor finalization logic in StreamWrapper and MessageStreamManagerWrapper to ensure idempotent behavior during context exit. - Introduce new methods for successful and error finalization, improving clarity and reducing code duplication. - Add tests to validate double exit idempotency in streaming scenarios, ensuring only one span is emitted. - Update cassettes to reflect new request and response structures for streaming interactions. * Enhance Anthropic instrumentation to support content capture - Added logger_provider to TelemetryHandler for improved logging capabilities. - Implemented content capture logic in messages_create and messages_stream functions, allowing for the extraction of input messages and system instructions. - Introduced utility functions for content conversion and message handling in utils.py. - Updated tests to validate content capture functionality for both synchronous and streaming message creation. - Added new cassettes to reflect the changes in request and response structures for content capture scenarios. * Enhance tests for sync message creation in Anthropic instrumentation - Added checks for the presence of 'tools' and 'thinking' parameters in the installed anthropic SDK. - Updated test cases to skip if the SDK version does not support these parameters, ensuring compatibility with older versions. - Improved test robustness by dynamically determining parameter support. * Remove sensitive 'anthropic-organization-id' headers from test cassettes and update header scrubbing logic in tests. This enhances security by ensuring sensitive information is not recorded in test artifacts. * Refactor tests for sync message handling in Anthropic instrumentation - Simplified detection of 'tools' and 'thinking' parameters by directly accessing the _Messages class. - Improved readability of test cases by formatting input message loading. - Enhanced test function signatures for better clarity and maintainability. * Refactor utils.py for improved type safety and clarity - Added type casting for dictionary access to enhance type safety. - Simplified content block conversion logic to improve readability and maintainability. - Updated test cases to ensure consistent handling of content types and structures. * Enhance Anthropic instrumentation tests for EVENT_ONLY content capture - Introduced a new fixture to instrument Anthropic with EVENT_ONLY content capture mode. - Added tests to verify that content is not captured in span attributes while ensuring log events are emitted correctly. - Updated cassettes to reflect new request and response structures for EVENT_ONLY scenarios. - Enhanced existing tests to cover various content capture scenarios, including streaming and tool usage. * Refactor assertion in sync messages test for clarity - Simplified the assertion statement in the test_sync_messages_create_event_only_no_content_in_span function to improve readability. * Refactor content capture logic and enhance streaming tests for Anthropic instrumentation. * unsetting the model. * Remove instrumentation for Messages.stream() and refactor related code. Introduced MessageWrapper and StreamWrapper classes for telemetry handling. Updated tests to reflect changes in instrumentation behavior. * Refactor Anthropic instrumentation: reorganize imports, enhance utility functions, and update wrapper classes for better clarity and maintainability. Removed unused code and improved type safety in utility functions. Updated tests to reflect changes in the instrumentation behavior. * Add message extractors for Anthropic instrumentation. * Refactor message extractors in Anthropic instrumentation: reorganize imports and streamline finish reason normalization for improved clarity and maintainability. * Update test cassettes for Anthropic instrumentation: streamline request and response structures, enhance error handling scenarios, and ensure consistency in message formats across various test cases. Removed outdated data and improved clarity in test interactions. * Enhance Anthropic instrumentation: update MessageWrapper and StreamWrapper to include content capture logic, improve type safety with explicit casting, and streamline test cases for better clarity. Added new test for streaming response attributes and refined existing tests to ensure consistency in message handling. * Update test cassettes for Anthropic instrumentation: modify message IDs, timestamps, and token usage across various test cases. Refine content capture logic and ensure consistency in message formats, including adjustments to event data and headers for improved clarity and accuracy. * Rename StreamWrapper to MessagesStreamWrapper and update references in code and tests * Refactor type annotations in message extractors and wrappers for improved type safety. Replace 'Any' with 'object' in several function signatures and class attributes. Introduce logging for error handling in MessagesStreamWrapper to enhance instrumentation reliability. * Enhance type annotations in message extractors and patch for improved clarity and safety. Update function signatures to use specific types instead of 'object', including changes to parameters in extract_params, get_input_messages, and get_system_instruction. Refactor messages_create to ensure correct type handling for streaming and non-streaming responses. Additionally, streamline message handling in MessagesStreamWrapper for better performance and reliability. * Enhance type safety and error handling in message processing. Update function signatures in `messages_extractors.py` and `wrappers.py` to include specific types, improving clarity and reliability. Introduce handling for `None` values in `get_input_messages` and `get_system_instruction`. Refactor `MessagesStreamWrapper` to better manage usage updates and ensure correct type handling for streaming responses. Add new test cases for aggregating cache tokens and handling streaming errors. * Refactor assertions in test_sync_messages.py for improved readability. Simplify assertion statements by removing unnecessary parentheses, enhancing code clarity in cache token tests. * enforce strong typing system. * Update anthropic dependency version to 0.51.0 in pyproject.toml and requirements.oldest.txt for compatibility improvements. * Refactor usage token extraction to utilize a new UsageTokens dataclass for improved clarity and type safety. Update extract_usage_tokens function to return UsageTokens instead of a tuple, and adjust related invocations in MessageWrapper and MessagesStreamWrapper accordingly. * Update anthropic dependency version in uv.lock to 0.51.0 for compatibility improvements. * Add tests for should_capture_content function in test_events_options.py. * Enhance Anthropic instrumentation by adding logging support and refining type hints in messages_create function. Update test cassettes for improved accuracy and consistency in response data. * Refactor content capturing utility function to clarify its purpose in experimental mode. Update related tests to reflect the new function name and ensure accurate assertions for content capturing behavior. * Refactor import statements in patch.py for improved readability and organization. --------- Co-authored-by: Aaron Abbott --- .../CHANGELOG.md | 5 + .../pyproject.toml | 2 +- .../instrumentation/anthropic/__init__.py | 7 +- .../anthropic/messages_extractors.py | 219 +++++ .../instrumentation/anthropic/patch.py | 115 ++- .../instrumentation/anthropic/utils.py | 328 +++++--- .../instrumentation/anthropic/wrappers.py | 275 +++++++ ...st_stream_wrapper_finalize_idempotent.yaml | 138 ++++ ...ssages_create_aggregates_cache_tokens.yaml | 140 ++++ .../test_sync_messages_create_api_error.yaml | 355 +------- .../test_sync_messages_create_basic.yaml | 761 +----------------- ...sync_messages_create_captures_content.yaml | 140 ++++ ...ages_create_captures_thinking_content.yaml | 149 ++++ ...ages_create_captures_tool_use_content.yaml | 168 ++++ ..._create_event_only_no_content_in_span.yaml | 140 ++++ ...reate_instrumentation_error_swallowed.yaml | 138 ++++ ...test_sync_messages_create_stop_reason.yaml | 436 +--------- ...sages_create_stream_propagation_error.yaml | 138 ++++ .../test_sync_messages_create_streaming.yaml | 138 ++++ ...ate_streaming_aggregates_cache_tokens.yaml | 138 ++++ ...ges_create_streaming_captures_content.yaml | 138 ++++ ...treaming_delegates_response_attribute.yaml | 147 ++++ ...c_messages_create_streaming_iteration.yaml | 147 ++++ ...sages_create_streaming_user_exception.yaml | 138 ++++ ...test_sync_messages_create_token_usage.yaml | 436 +--------- ..._sync_messages_create_with_all_params.yaml | 464 +---------- .../tests/conftest.py | 83 +- .../tests/requirements.oldest.txt | 3 +- .../tests/test_sync_messages.py | 655 ++++++++++++++- .../src/opentelemetry/util/genai/utils.py | 12 + .../tests/test_events_options.py | 43 + uv.lock | 2 +- 32 files changed, 3684 insertions(+), 2514 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/messages_extractors.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_stream_wrapper_finalize_idempotent.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_aggregates_cache_tokens.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_thinking_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_tool_use_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_event_only_no_content_in_span.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_instrumentation_error_swallowed.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_stream_propagation_error.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_aggregates_cache_tokens.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_captures_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_delegates_response_attribute.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_iteration.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_user_exception.yaml diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-anthropic/CHANGELOG.md index ba164c0ebc8..5cf210fbd14 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Add sync streaming support for `Messages.create(stream=True)` and `Messages.stream()` + ([#4155](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4155)) + - `StreamWrapper` for handling `Messages.create(stream=True)` telemetry + - `MessageStreamManagerWrapper` for handling `Messages.stream()` telemetry + - `MessageWrapper` for non-streaming response telemetry extraction - Initial implementation of Anthropic instrumentation ([#3978](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3978)) - Implement sync `Messages.create` instrumentation with GenAI semantic convention attributes diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml index 32642eaf2be..74c411a1a5c 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "anthropic >= 0.16.0", + "anthropic >= 0.51.0", ] [project.entry-points.opentelemetry_instrumentor] diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/__init__.py index bf76798462b..f5286438a40 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/__init__.py @@ -54,7 +54,9 @@ ) from opentelemetry.instrumentation.anthropic.package import _instruments -from opentelemetry.instrumentation.anthropic.patch import messages_create +from opentelemetry.instrumentation.anthropic.patch import ( + messages_create, +) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.utils import unwrap from opentelemetry.util.genai.handler import TelemetryHandler @@ -89,11 +91,12 @@ def _instrument(self, **kwargs: Any) -> None: # Get providers from kwargs tracer_provider = kwargs.get("tracer_provider") meter_provider = kwargs.get("meter_provider") + logger_provider = kwargs.get("logger_provider") - # TODO: Add logger_provider to TelemetryHandler to capture content events. handler = TelemetryHandler( tracer_provider=tracer_provider, meter_provider=meter_provider, + logger_provider=logger_provider, ) # Patch Messages.create diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/messages_extractors.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/messages_extractors.py new file mode 100644 index 00000000000..907aa08d39d --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/messages_extractors.py @@ -0,0 +1,219 @@ +# 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. + +"""Get/extract helpers for Anthropic Messages instrumentation.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, Sequence + +from anthropic.types import MessageDeltaUsage + +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) +from opentelemetry.util.genai.types import ( + InputMessage, + MessagePart, + OutputMessage, +) +from opentelemetry.util.types import AttributeValue + +from .utils import ( + convert_content_to_parts, + normalize_finish_reason, +) + +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + import httpx + from anthropic.resources.messages import Messages + from anthropic.types import ( + Message, + MessageParam, + MetadataParam, + TextBlockParam, + ThinkingConfigParam, + ToolChoiceParam, + ToolUnionParam, + Usage, + ) + + +@dataclass +class MessageRequestParams: + model: str | None = None + max_tokens: int | None = None + temperature: float | None = None + top_k: int | None = None + top_p: float | None = None + stop_sequences: Sequence[str] | None = None + stream: bool | None = None + messages: Iterable[MessageParam] | None = None + system: str | Iterable[TextBlockParam] | None = None + + +GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS = ( + "gen_ai.usage.cache_creation.input_tokens" +) +GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS = "gen_ai.usage.cache_read.input_tokens" + + +@dataclass +class UsageTokens: + input_tokens: int | None = None + output_tokens: int | None = None + cache_creation_input_tokens: int | None = None + cache_read_input_tokens: int | None = None + + +def extract_usage_tokens( + usage: Usage | MessageDeltaUsage | None, +) -> UsageTokens: + if usage is None: + return UsageTokens() + + input_tokens = usage.input_tokens + output_tokens = usage.output_tokens + cache_creation_input_tokens = usage.cache_creation_input_tokens + cache_read_input_tokens = usage.cache_read_input_tokens + + if ( + input_tokens is None + and cache_creation_input_tokens is None + and cache_read_input_tokens is None + ): + total_input_tokens = None + else: + total_input_tokens = ( + (input_tokens or 0) + + (cache_creation_input_tokens or 0) + + (cache_read_input_tokens or 0) + ) + + return UsageTokens( + input_tokens=total_input_tokens, + output_tokens=output_tokens, + cache_creation_input_tokens=cache_creation_input_tokens, + cache_read_input_tokens=cache_read_input_tokens, + ) + + +def get_input_messages( + messages: Iterable[MessageParam] | None, +) -> list[InputMessage]: + if messages is None: + return [] + result: list[InputMessage] = [] + for message in messages: + role = message["role"] + parts = convert_content_to_parts(message["content"]) + result.append(InputMessage(role=role, parts=parts)) + return result + + +def get_system_instruction( + system: str | Iterable[TextBlockParam] | None, +) -> list[MessagePart]: + if system is None: + return [] + return convert_content_to_parts(system) + + +def get_output_messages_from_message( + message: Message | None, +) -> list[OutputMessage]: + if message is None: + return [] + + parts = convert_content_to_parts(message.content) + finish_reason = normalize_finish_reason(message.stop_reason) + return [ + OutputMessage( + role=message.role, + parts=parts, + finish_reason=finish_reason or "", + ) + ] + + +def extract_params( # pylint: disable=too-many-locals + *, + max_tokens: int | None = None, + messages: Iterable[MessageParam] | None = None, + model: str | None = None, + metadata: MetadataParam | None = None, + service_tier: str | None = None, + stop_sequences: Sequence[str] | None = None, + stream: bool | None = None, + system: str | Iterable[TextBlockParam] | None = None, + temperature: float | None = None, + thinking: ThinkingConfigParam | None = None, + tool_choice: ToolChoiceParam | None = None, + tools: Iterable[ToolUnionParam] | None = None, + top_k: int | None = None, + top_p: float | None = None, + extra_headers: Mapping[str, str] | None = None, + extra_query: Mapping[str, object] | None = None, + extra_body: object | None = None, + timeout: float | httpx.Timeout | None = None, + **_kwargs: object, +) -> MessageRequestParams: + return MessageRequestParams( + model=model, + max_tokens=max_tokens, + temperature=temperature, + top_p=top_p, + top_k=top_k, + stop_sequences=stop_sequences, + stream=stream, + messages=messages, + system=system, + ) + + +def _set_server_address_and_port( + client_instance: "Messages", + attributes: dict[str, AttributeValue | None], +) -> None: + base_url = client_instance._client.base_url + host = base_url.host + if host: + attributes[ServerAttributes.SERVER_ADDRESS] = host + + port = base_url.port + if port and port != 443 and port > 0: + attributes[ServerAttributes.SERVER_PORT] = port + + +def get_llm_request_attributes( + params: MessageRequestParams, client_instance: "Messages" +) -> dict[str, AttributeValue]: + attributes: dict[str, AttributeValue | None] = { + GenAIAttributes.GEN_AI_OPERATION_NAME: GenAIAttributes.GenAiOperationNameValues.CHAT.value, + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.ANTHROPIC.value, # pyright: ignore[reportDeprecated] + GenAIAttributes.GEN_AI_REQUEST_MODEL: params.model, + GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS: params.max_tokens, + GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE: params.temperature, + GenAIAttributes.GEN_AI_REQUEST_TOP_P: params.top_p, + GenAIAttributes.GEN_AI_REQUEST_TOP_K: params.top_k, + GenAIAttributes.GEN_AI_REQUEST_STOP_SEQUENCES: params.stop_sequences, + } + _set_server_address_and_port(client_instance, attributes) + return {k: v for k, v in attributes.items() if v is not None} diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py index 0562d638e23..2392dfcd08f 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py @@ -14,65 +14,120 @@ """Patching functions for Anthropic instrumentation.""" -from typing import TYPE_CHECKING, Any, Callable +import logging +from typing import TYPE_CHECKING, Any, Callable, Union, cast + +from anthropic._streaming import Stream as AnthropicStream +from anthropic.types import Message as AnthropicMessage from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, ) from opentelemetry.util.genai.handler import TelemetryHandler -from opentelemetry.util.genai.types import LLMInvocation +from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.utils import ( + should_capture_content_on_spans_in_experimental_mode, +) -from .utils import ( +from .messages_extractors import ( extract_params, + get_input_messages, get_llm_request_attributes, + get_system_instruction, +) +from .wrappers import ( + MessagesStreamWrapper, + MessageWrapper, ) if TYPE_CHECKING: from anthropic.resources.messages import Messages - from anthropic.types import Message + from anthropic.types import RawMessageStreamEvent + + +_logger = logging.getLogger(__name__) +ANTHROPIC = "anthropic" def messages_create( handler: TelemetryHandler, -) -> Callable[..., "Message"]: +) -> Callable[ + ..., + Union[ + "AnthropicMessage", + "AnthropicStream[RawMessageStreamEvent]", + MessagesStreamWrapper, + ], +]: """Wrap the `create` method of the `Messages` class to trace it.""" + capture_content = should_capture_content_on_spans_in_experimental_mode() def traced_method( - wrapped: Callable[..., "Message"], + wrapped: Callable[ + ..., + Union[ + "AnthropicMessage", + "AnthropicStream[RawMessageStreamEvent]", + ], + ], instance: "Messages", args: tuple[Any, ...], kwargs: dict[str, Any], - ) -> "Message": + ) -> Union[ + "AnthropicMessage", + "AnthropicStream[RawMessageStreamEvent]", + MessagesStreamWrapper, + ]: params = extract_params(*args, **kwargs) attributes = get_llm_request_attributes(params, instance) - request_model = str( - attributes.get(GenAIAttributes.GEN_AI_REQUEST_MODEL) - or params.model - or "unknown" + request_model_attribute = attributes.get( + GenAIAttributes.GEN_AI_REQUEST_MODEL + ) + request_model = ( + request_model_attribute + if isinstance(request_model_attribute, str) + else params.model ) invocation = LLMInvocation( request_model=request_model, - provider="anthropic", + provider=ANTHROPIC, + input_messages=get_input_messages(params.messages) + if capture_content + else [], + system_instruction=get_system_instruction(params.system) + if capture_content + else [], attributes=attributes, ) - with handler.llm(invocation) as invocation: + # Use manual lifecycle management for both streaming and non-streaming + handler.start_llm(invocation) + try: result = wrapped(*args, **kwargs) - - if result.model: - invocation.response_model_name = result.model - - if result.id: - invocation.response_id = result.id - - if result.stop_reason: - invocation.finish_reasons = [result.stop_reason] - - if result.usage: - invocation.input_tokens = result.usage.input_tokens - invocation.output_tokens = result.usage.output_tokens - - return result - - return traced_method + if isinstance(result, AnthropicStream): + return MessagesStreamWrapper( + result, handler, invocation, capture_content + ) + + wrapper = MessageWrapper(result, capture_content) + wrapper.extract_into(invocation) + handler.stop_llm(invocation) + return wrapper.message + except Exception as exc: + handler.fail_llm( + invocation, Error(message=str(exc), type=type(exc)) + ) + raise + + return cast( + Callable[ + ..., + Union[ + "AnthropicMessage", + "AnthropicStream[RawMessageStreamEvent]", + MessagesStreamWrapper, + ], + ], + traced_method, + ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/utils.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/utils.py index 4c2003f4410..9914a55a227 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/utils.py @@ -12,134 +12,230 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Utility functions for Anthropic instrumentation.""" +"""Shared helper utilities for Anthropic instrumentation.""" from __future__ import annotations +import base64 +import json from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Optional, Sequence -from urllib.parse import urlparse - -from opentelemetry.semconv._incubating.attributes import ( - gen_ai_attributes as GenAIAttributes, +from typing import TYPE_CHECKING, Any + +from anthropic.types import ( + InputJSONDelta, + RedactedThinkingBlock, + ServerToolUseBlock, + TextBlock, + TextDelta, + ThinkingBlock, + ThinkingDelta, + ToolUseBlock, + WebSearchToolResultBlock, ) -from opentelemetry.semconv._incubating.attributes import ( - server_attributes as ServerAttributes, + +from opentelemetry.util.genai.types import ( + Blob, + MessagePart, + Reasoning, + Text, + ToolCall, + ToolCallResponse, ) -from opentelemetry.util.types import AttributeValue if TYPE_CHECKING: - from anthropic.resources.messages import Messages + from collections.abc import Iterable, Mapping + + from anthropic.types import ( + ContentBlock, + ContentBlockParam, + RawContentBlockDelta, + ) @dataclass -class MessageCreateParams: - """Parameters extracted from Messages.create() call.""" - - model: str | None = None - max_tokens: int | None = None - temperature: float | None = None - top_p: float | None = None - top_k: int | None = None - stop_sequences: Sequence[str] | None = None - - -# Use parameter signature from -# https://github.com/anthropics/anthropic-sdk-python/blob/9b5ab24ba17bcd5e762e5a5fd69bb3c17b100aaa/src/anthropic/resources/messages/messages.py#L92 -# to handle named vs positional args robustly -def extract_params( # pylint: disable=too-many-locals - *, - max_tokens: int | None = None, - messages: Any | None = None, - model: str | None = None, - metadata: Any | None = None, - service_tier: Any | None = None, - stop_sequences: Sequence[str] | None = None, - stream: Any | None = None, - system: Any | None = None, - temperature: float | None = None, - thinking: Any | None = None, - tool_choice: Any | None = None, - tools: Any | None = None, - top_p: float | None = None, - top_k: int | None = None, - extra_headers: Any | None = None, - extra_query: Any | None = None, - extra_body: Any | None = None, - timeout: Any | None = None, - **_kwargs: Any, -) -> MessageCreateParams: - """Extract relevant parameters from Messages.create() arguments.""" - return MessageCreateParams( - model=model, - max_tokens=max_tokens, - temperature=temperature, - top_p=top_p, - top_k=top_k, - stop_sequences=stop_sequences, +class StreamBlockState: + type: str + text: str = "" + tool_id: str | None = None + tool_name: str = "" + tool_input: dict[str, object] | None = None + input_json: str = "" + thinking: str = "" + + +def normalize_finish_reason(stop_reason: str | None) -> str | None: + if stop_reason is None: + return None + normalized = { + "end_turn": "stop", + "stop_sequence": "stop", + "max_tokens": "length", + "tool_use": "tool_calls", + }.get(stop_reason) + return normalized or stop_reason + + +def _decode_base64(data: str) -> bytes | None: + try: + return base64.b64decode(data) + except Exception: # pylint: disable=broad-exception-caught + return None + + +def _extract_base64_blob(source: object, modality: str) -> Blob | None: + """Extract a Blob from a base64-encoded source dict.""" + if not isinstance(source, dict): + return None + # source is a TypedDict (e.g. Base64ImageSourceParam) narrowed to dict; + # pyright cannot infer value types from isinstance-narrowed dicts. + data: object = source.get("data") # type: ignore[reportUnknownMemberType] + if not isinstance(data, str): + return None + decoded = _decode_base64(data) + if decoded is None: + return None + media_type: object = source.get("media_type") # type: ignore[reportUnknownMemberType] + return Blob( + mime_type=media_type if isinstance(media_type, str) else None, + modality=modality, + content=decoded, ) -def set_server_address_and_port( - client_instance: "Messages", attributes: dict[str, Any] +def _convert_dict_block_to_part( + block: Mapping[str, Any], +) -> MessagePart | None: + """Convert a request-param content block (TypedDict/dict) to a MessagePart.""" + block_type = block.get("type") + + if block_type == "text": + text = block.get("text") + return Text(content=str(text) if text is not None else "") + + if block_type == "tool_use": + inp = block.get("input") + return ToolCall( + arguments=inp if isinstance(inp, dict) else None, + name=str(block.get("name", "")), + id=str(block.get("id", "")), + ) + + if block_type == "tool_result": + return ToolCallResponse( + response=block.get("content"), + id=str(block.get("tool_use_id", "")), + ) + + if block_type in ("thinking", "redacted_thinking"): + thinking = block.get("thinking") or block.get("data") + return Reasoning(content=str(thinking) if thinking is not None else "") + + if block_type in ("image", "audio", "video", "document", "file"): + return _extract_base64_blob(block.get("source"), str(block_type)) + + return None + + +def _convert_content_block_to_part( + block: ContentBlock | ContentBlockParam, +) -> MessagePart | None: + """Convert an Anthropic content block to a MessagePart.""" + if isinstance(block, TextBlock): + return Text(content=block.text) + + if isinstance(block, (ToolUseBlock, ServerToolUseBlock)): + return ToolCall(arguments=block.input, name=block.name, id=block.id) + + if isinstance(block, (ThinkingBlock, RedactedThinkingBlock)): + content = ( + block.thinking if isinstance(block, ThinkingBlock) else block.data + ) + return Reasoning(content=content) + + if isinstance(block, WebSearchToolResultBlock): + return ToolCallResponse( + response=block.model_dump().get("content"), + id=block.tool_use_id, + ) + + # ContentBlockParam variants are TypedDicts (dicts at runtime); + # newer SDK versions may add Pydantic block types not handled above. + if isinstance(block, dict): + return _convert_dict_block_to_part(block) + + return None + + +def convert_content_to_parts( + content: str | Iterable[ContentBlock | ContentBlockParam] | None, +) -> list[MessagePart]: + if content is None: + return [] + if isinstance(content, str): + return [Text(content=content)] + parts: list[MessagePart] = [] + for item in content: + part = _convert_content_block_to_part(item) + if part is not None: + parts.append(part) + return parts + + +def create_stream_block_state(content_block: ContentBlock) -> StreamBlockState: + if isinstance(content_block, TextBlock): + return StreamBlockState(type="text", text=content_block.text) + + if isinstance(content_block, (ToolUseBlock, ServerToolUseBlock)): + return StreamBlockState( + type="tool_use", + tool_id=content_block.id, + tool_name=content_block.name, + tool_input=content_block.input, + ) + + if isinstance(content_block, ThinkingBlock): + return StreamBlockState( + type="thinking", thinking=content_block.thinking + ) + + if isinstance(content_block, RedactedThinkingBlock): + return StreamBlockState(type="redacted_thinking") + + return StreamBlockState(type=content_block.type) + + +def update_stream_block_state( + state: StreamBlockState, delta: RawContentBlockDelta ) -> None: - """Extract server address and port from the Anthropic client instance.""" - base_client = getattr(client_instance, "_client", None) - base_url = getattr(base_client, "base_url", None) - if not base_url: - return - - port: Optional[int] = None - if hasattr(base_url, "host"): - # httpx.URL object - attributes[ServerAttributes.SERVER_ADDRESS] = base_url.host - port = getattr(base_url, "port", None) - elif isinstance(base_url, str): - url = urlparse(base_url) - attributes[ServerAttributes.SERVER_ADDRESS] = url.hostname - port = url.port - - if port and port != 443 and port > 0: - attributes[ServerAttributes.SERVER_PORT] = port - - -def get_llm_request_attributes( - params: MessageCreateParams, client_instance: "Messages" -) -> dict[str, AttributeValue]: - """Extract LLM request attributes from MessageCreateParams. - - Returns a dictionary of OpenTelemetry semantic convention attributes for LLM requests. - The attributes follow the GenAI semantic conventions (gen_ai.*) and server semantic - conventions (server.*) as defined in the OpenTelemetry specification. - - GenAI attributes included: - - gen_ai.operation.name: The operation name (e.g., "chat") - - gen_ai.system: The GenAI system identifier (e.g., "anthropic") - - gen_ai.request.model: The model identifier - - gen_ai.request.max_tokens: Maximum tokens in the request - - gen_ai.request.temperature: Sampling temperature - - gen_ai.request.top_p: Top-p sampling parameter - - gen_ai.request.top_k: Top-k sampling parameter - - gen_ai.request.stop_sequences: Stop sequences for the request - - Server attributes included (if available): - - server.address: The server hostname - - server.port: The server port (if not default 443) - - Only non-None values are included in the returned dictionary. - """ - attributes = { - GenAIAttributes.GEN_AI_OPERATION_NAME: GenAIAttributes.GenAiOperationNameValues.CHAT.value, - GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.ANTHROPIC.value, # pyright: ignore[reportDeprecated] - GenAIAttributes.GEN_AI_REQUEST_MODEL: params.model, - GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS: params.max_tokens, - GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE: params.temperature, - GenAIAttributes.GEN_AI_REQUEST_TOP_P: params.top_p, - GenAIAttributes.GEN_AI_REQUEST_TOP_K: params.top_k, - GenAIAttributes.GEN_AI_REQUEST_STOP_SEQUENCES: params.stop_sequences, - } - - set_server_address_and_port(client_instance, attributes) - - # Filter out None values - return {k: v for k, v in attributes.items() if v is not None} + if isinstance(delta, TextDelta): + state.type = "text" + state.text += delta.text + elif isinstance(delta, InputJSONDelta): + state.type = "tool_use" + state.input_json += delta.partial_json + elif isinstance(delta, ThinkingDelta): + state.type = "thinking" + state.thinking += delta.thinking + + +def stream_block_state_to_part(state: StreamBlockState) -> MessagePart | None: + if state.type == "text": + return Text(content=state.text) + + if state.type == "tool_use": + arguments: str | dict[str, object] | None = state.tool_input + if state.input_json: + try: + arguments = json.loads(state.input_json) + except ValueError: + arguments = state.input_json + return ToolCall( + arguments=arguments, + name=state.tool_name, + id=state.tool_id, + ) + + if state.type in ("thinking", "redacted_thinking"): + return Reasoning(content=state.thinking) + + return None diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py new file mode 100644 index 00000000000..585d70a9f97 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py @@ -0,0 +1,275 @@ +# 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 __future__ import annotations + +import logging +from types import TracebackType +from typing import TYPE_CHECKING, Callable, Iterator, Optional + +from opentelemetry.util.genai.handler import TelemetryHandler +from opentelemetry.util.genai.types import ( + Error, + LLMInvocation, + MessagePart, + OutputMessage, +) + +from .messages_extractors import ( + GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, + GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, + extract_usage_tokens, + get_output_messages_from_message, +) +from .utils import ( + StreamBlockState, + create_stream_block_state, + normalize_finish_reason, + stream_block_state_to_part, + update_stream_block_state, +) + +if TYPE_CHECKING: + from anthropic._streaming import Stream + from anthropic.types import ( + Message, + MessageDeltaUsage, + RawMessageStreamEvent, + Usage, + ) + + +_logger = logging.getLogger(__name__) + + +class MessageWrapper: + """Wrapper for non-streaming Message response that handles telemetry.""" + + def __init__(self, message: Message, capture_content: bool): + self._message = message + self._capture_content = capture_content + + def extract_into(self, invocation: LLMInvocation) -> None: + """Extract response data into the invocation.""" + if self._message.model: + invocation.response_model_name = self._message.model + + if self._message.id: + invocation.response_id = self._message.id + + finish_reason = normalize_finish_reason(self._message.stop_reason) + if finish_reason: + invocation.finish_reasons = [finish_reason] + + if self._message.usage: + tokens = extract_usage_tokens(self._message.usage) + invocation.input_tokens = tokens.input_tokens + invocation.output_tokens = tokens.output_tokens + if tokens.cache_creation_input_tokens is not None: + invocation.attributes[ + GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS + ] = tokens.cache_creation_input_tokens + if tokens.cache_read_input_tokens is not None: + invocation.attributes[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] = ( + tokens.cache_read_input_tokens + ) + + if self._capture_content: + invocation.output_messages = get_output_messages_from_message( + self._message + ) + + @property + def message(self) -> Message: + """Return the wrapped Message object.""" + return self._message + + +class MessagesStreamWrapper(Iterator["RawMessageStreamEvent"]): + """Wrapper for Anthropic Stream that handles telemetry.""" + + def __init__( + self, + stream: Stream[RawMessageStreamEvent], + handler: TelemetryHandler, + invocation: LLMInvocation, + capture_content: bool, + ): + self._stream = stream + self._handler = handler + self._invocation = invocation + self._response_id: Optional[str] = None + self._response_model: Optional[str] = None + self._stop_reason: Optional[str] = None + self._input_tokens: Optional[int] = None + self._output_tokens: Optional[int] = None + self._cache_creation_input_tokens: Optional[int] = None + self._cache_read_input_tokens: Optional[int] = None + self._capture_content = capture_content + self._content_blocks: dict[int, StreamBlockState] = {} + self._finalized = False + + def _update_usage(self, usage: Usage | MessageDeltaUsage | None) -> None: + tokens = extract_usage_tokens(usage) + if tokens.input_tokens is not None: + self._input_tokens = tokens.input_tokens + if tokens.output_tokens is not None: + self._output_tokens = tokens.output_tokens + if tokens.cache_creation_input_tokens is not None: + self._cache_creation_input_tokens = ( + tokens.cache_creation_input_tokens + ) + if tokens.cache_read_input_tokens is not None: + self._cache_read_input_tokens = tokens.cache_read_input_tokens + + def _process_chunk(self, chunk: RawMessageStreamEvent) -> None: + """Extract telemetry data from a streaming chunk.""" + if chunk.type == "message_start": + message = chunk.message + if message.id: + self._response_id = message.id + if message.model: + self._response_model = message.model + self._update_usage(message.usage) + elif chunk.type == "message_delta": + if chunk.delta.stop_reason: + self._stop_reason = normalize_finish_reason( + chunk.delta.stop_reason + ) + self._update_usage(chunk.usage) + elif self._capture_content and chunk.type == "content_block_start": + self._content_blocks[chunk.index] = create_stream_block_state( + chunk.content_block + ) + elif self._capture_content and chunk.type == "content_block_delta": + block = self._content_blocks.get(chunk.index) + if block is not None: + update_stream_block_state(block, chunk.delta) + + @staticmethod + def _safe_instrumentation( + callback: Callable[[], object], context: str + ) -> None: + try: + callback() + except Exception: # pylint: disable=broad-exception-caught + _logger.debug( + "Anthropic MessagesStreamWrapper instrumentation error in %s", + context, + exc_info=True, + ) + + def _set_invocation_response_attributes(self) -> None: + """Extract accumulated stream state into the invocation.""" + if self._response_model: + self._invocation.response_model_name = self._response_model + if self._response_id: + self._invocation.response_id = self._response_id + if self._stop_reason: + self._invocation.finish_reasons = [self._stop_reason] + if self._input_tokens is not None: + self._invocation.input_tokens = self._input_tokens + if self._output_tokens is not None: + self._invocation.output_tokens = self._output_tokens + if self._cache_creation_input_tokens is not None: + self._invocation.attributes[ + GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS + ] = self._cache_creation_input_tokens + if self._cache_read_input_tokens is not None: + self._invocation.attributes[ + GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS + ] = self._cache_read_input_tokens + + if self._capture_content and self._content_blocks: + parts: list[MessagePart] = [] + for index in sorted(self._content_blocks): + part = stream_block_state_to_part(self._content_blocks[index]) + if part is not None: + parts.append(part) + self._invocation.output_messages = [ + OutputMessage( + role="assistant", + parts=parts, + finish_reason=self._stop_reason or "", + ) + ] + + def _stop(self) -> None: + if self._finalized: + return + self._safe_instrumentation( + self._set_invocation_response_attributes, + "response attribute extraction", + ) + self._safe_instrumentation( + lambda: self._handler.stop_llm(self._invocation), + "stop_llm", + ) + self._finalized = True + + def _fail(self, message: str, error_type: type[BaseException]) -> None: + if self._finalized: + return + self._safe_instrumentation( + lambda: self._handler.fail_llm( + self._invocation, Error(message=message, type=error_type) + ), + "fail_llm", + ) + self._finalized = True + + def __iter__(self) -> MessagesStreamWrapper: + return self + + def __getattr__(self, name: str) -> object: + return getattr(self._stream, name) + + def __next__(self) -> RawMessageStreamEvent: + try: + chunk = next(self._stream) + except StopIteration: + self._stop() + raise + except Exception as exc: + self._fail(str(exc), type(exc)) + raise + self._safe_instrumentation( + lambda: self._process_chunk(chunk), + "stream chunk processing", + ) + return chunk + + def __enter__(self) -> MessagesStreamWrapper: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + try: + if exc_type is not None: + self._fail( + str(exc_val), type(exc_val) if exc_val else Exception + ) + finally: + self.close() + return False + + def close(self) -> None: + try: + self._stream.close() + finally: + self._stop() diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_stream_wrapper_finalize_idempotent.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_stream_wrapper_finalize_idempotent.yaml new file mode 100644 index 00000000000..742ed18b4f5 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_stream_wrapper_finalize_idempotent.yaml @@ -0,0 +1,138 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '131' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01SzbrAKmQ4WKrcUssAJsSf3","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello!"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":5} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + CF-RAY: + - 9d65684f6e3fe0c6-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:21 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:20Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:20Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:20Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:20Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1141' + request-id: + - req_011CYfQNsrQ5w1kPtYjmXzeP + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '1051' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_aggregates_cache_tokens.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_aggregates_cache_tokens.yaml new file mode 100644 index 00000000000..db527c89c36 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_aggregates_cache_tokens.yaml @@ -0,0 +1,140 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '117' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - '600' + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |- + { + "model": "claude-sonnet-4-20250514", + "id": "msg_01QnfZn8pVXgBGu2wtj3EZKJ", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Hello!" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 13, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 5, + "service_tier": "standard", + "inference_geo": "not_available" + } + } + headers: + CF-RAY: + - 9d656857bc9cc794-EWR + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Tue, 03 Mar 2026 03:03:22 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:22Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:22Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:21Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:22Z' + cf-cache-status: + - DYNAMIC + content-length: + - '441' + request-id: + - req_011CYfQNyftvAdchCgU7PwhE + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '911' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_api_error.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_api_error.yaml index 39405821987..875ba824e67 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_api_error.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_api_error.yaml @@ -1,343 +1,4 @@ interactions: -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Hello" - } - ], - "model": "invalid-model-name" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '110' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python - x-api-key: - - test_anthropic_api_key - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "not_found_error", - "message": "model: invalid-model-name" - } - } - headers: - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 15 Dec 2024 10:00:04 GMT - Server: - - cloudflare - content-length: - - '105' - status: - code: 404 - message: Not Found -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Hello" - } - ], - "model": "invalid-model-name" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '94' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "authentication_error", - "message": "invalid x-api-key" - }, - "request_id": "req_011CX88XGWSm82bN96ZkDWcr" - } - headers: - CF-RAY: - - 9be0e03eff016e28-EWR - Connection: - - keep-alive - Content-Length: - - '130' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:22:32 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88XGWSm82bN96ZkDWcr - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '13' - x-should-retry: - - 'false' - status: - code: 401 - message: Unauthorized -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Hello" - } - ], - "model": "invalid-model-name" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '94' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "invalid_request_error", - "message": "Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits." - }, - "request_id": "req_011CX88ZmBumGkvj7aK6Gqzx" - } - headers: - CF-RAY: - - 9be0e1127fd1b1bc-EWR - Connection: - - keep-alive - Content-Length: - - '234' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:23:06 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88ZmBumGkvj7aK6Gqzx - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '59' - x-should-retry: - - 'false' - status: - code: 400 - message: Bad Request -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Hello" - } - ], - "model": "invalid-model-name" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '94' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "not_found_error", - "message": "model: invalid-model-name" - }, - "request_id": "req_011CX89f9XqPgyRJC1ASfAab" - } - headers: - CF-RAY: - - 9be0f610add5b89f-EWR - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:37:25 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - cf-cache-status: - - DYNAMIC - content-length: - - '133' - request-id: - - req_011CX89f9XqPgyRJC1ASfAab - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '27' - x-should-retry: - - 'false' - status: - code: 404 - message: Not Found - request: body: |- { @@ -400,35 +61,37 @@ interactions: "type": "not_found_error", "message": "model: invalid-model-name" }, - "request_id": "req_011CX89kiWcGNsjEPrPGA42x" + "request_id": "req_011CYfQMhgSid28ainNjq126" } headers: CF-RAY: - - 9be0f7e8dbf70ab9-EWR + - 9d6567ebcfafc4fb-EWR Connection: - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' Content-Type: - application/json Date: - - Wed, 14 Jan 2026 23:38:41 GMT + - Tue, 03 Mar 2026 03:03:04 GMT Server: - cloudflare Transfer-Encoding: - chunked X-Robots-Tag: - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 cf-cache-status: - DYNAMIC content-length: - '133' request-id: - - req_011CX89kiWcGNsjEPrPGA42x + - req_011CYfQMhgSid28ainNjq126 strict-transport-security: - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding x-envoy-upstream-service-time: - - '78' + - '28' x-should-retry: - 'false' status: diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_basic.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_basic.yaml index 205b1c2e499..f7c1cab070a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_basic.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_basic.yaml @@ -1,720 +1,4 @@ interactions: -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hello in one word." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '128' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python - x-api-key: - - test_anthropic_api_key - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "id": "msg_01XFDUDYJgAACzvnptvVoYEL", - "type": "message", - "role": "assistant", - "model": "claude-3-5-sonnet-20241022", - "content": [ - { - "type": "text", - "text": "Hello!" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 14, - "output_tokens": 4 - } - } - headers: - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 15 Dec 2024 10:00:00 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - content-length: - - '350' - status: - code: 200 - message: OK -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hello in one word." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '119' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "authentication_error", - "message": "invalid x-api-key" - }, - "request_id": "req_011CX88X7DM3SrsuuERgZeYJ" - } - headers: - CF-RAY: - - 9be0e0315fa2a02c-EWR - Connection: - - keep-alive - Content-Length: - - '130' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:22:30 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88X7DM3SrsuuERgZeYJ - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '13' - x-should-retry: - - 'false' - status: - code: 401 - message: Unauthorized -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hello in one word." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '119' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "invalid_request_error", - "message": "Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits." - }, - "request_id": "req_011CX88Zakc7NS5rDAkMMK45" - } - headers: - CF-RAY: - - 9be0e1032e73ace5-EWR - Connection: - - keep-alive - Content-Length: - - '234' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:23:03 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88Zakc7NS5rDAkMMK45 - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '30' - x-should-retry: - - 'false' - status: - code: 400 - message: Bad Request -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hello in one word." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '119' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "invalid_request_error", - "message": "Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits." - }, - "request_id": "req_011CX88qYh2YvHnk7Hp8vCR7" - } - headers: - CF-RAY: - - 9be0e64cc92eb4c6-EWR - Connection: - - keep-alive - Content-Length: - - '234' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:26:40 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88qYh2YvHnk7Hp8vCR7 - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '20' - x-should-retry: - - 'false' - status: - code: 400 - message: Bad Request -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hello in one word." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '119' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "not_found_error", - "message": "model: claude-3-5-sonnet-20241022" - }, - "request_id": "req_011CX89Wba1H8DoNZMAq5M9M" - } - headers: - CF-RAY: - - 9be0f33baa01cdf0-EWR - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:35:29 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - cf-cache-status: - - DYNAMIC - content-length: - - '141' - request-id: - - req_011CX89Wba1H8DoNZMAq5M9M - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '28' - x-should-retry: - - 'false' - status: - code: 404 - message: Not Found -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hello in one word." - } - ], - "model": "claude-sonnet-4-20250514" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '117' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "model": "claude-sonnet-4-20250514", - "id": "msg_01ChhLEFb4TSQWHpQzFqEQsj", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Hello!" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 13, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 5, - "service_tier": "standard" - } - } - headers: - CF-RAY: - - 9be0f55b2b560866-EWR - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:36:58 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - anthropic-ratelimit-input-tokens-limit: - - '30000' - anthropic-ratelimit-input-tokens-remaining: - - '30000' - anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:36:58Z' - anthropic-ratelimit-output-tokens-limit: - - '8000' - anthropic-ratelimit-output-tokens-remaining: - - '8000' - anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:36:58Z' - anthropic-ratelimit-requests-limit: - - '50' - anthropic-ratelimit-requests-remaining: - - '49' - anthropic-ratelimit-requests-reset: - - '2026-01-14T23:36:58Z' - anthropic-ratelimit-tokens-limit: - - '38000' - anthropic-ratelimit-tokens-remaining: - - '38000' - anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:36:58Z' - cf-cache-status: - - DYNAMIC - content-length: - - '409' - request-id: - - req_011CX89d1Mu8qapBc5y9KdXf - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '1596' - status: - code: 200 - message: OK -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hello in one word." - } - ], - "model": "claude-sonnet-4-20250514" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '117' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "model": "claude-sonnet-4-20250514", - "id": "msg_01W7B22k9o9QrCqiEWmU1v9G", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Hello!" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 13, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 5, - "service_tier": "standard" - } - } - headers: - CF-RAY: - - 9be0f5d0cffcdcde-EWR - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:37:17 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - anthropic-ratelimit-input-tokens-limit: - - '30000' - anthropic-ratelimit-input-tokens-remaining: - - '30000' - anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:37:16Z' - anthropic-ratelimit-output-tokens-limit: - - '8000' - anthropic-ratelimit-output-tokens-remaining: - - '8000' - anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:37:17Z' - anthropic-ratelimit-requests-limit: - - '50' - anthropic-ratelimit-requests-remaining: - - '49' - anthropic-ratelimit-requests-reset: - - '2026-01-14T23:37:16Z' - anthropic-ratelimit-tokens-limit: - - '38000' - anthropic-ratelimit-tokens-remaining: - - '38000' - anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:37:16Z' - cf-cache-status: - - DYNAMIC - content-length: - - '409' - request-id: - - req_011CX89ePqXjam4ByzovDWC6 - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '1516' - status: - code: 200 - message: OK - request: body: |- { @@ -773,7 +57,7 @@ interactions: string: |- { "model": "claude-sonnet-4-20250514", - "id": "msg_01MpMMdwiz43MhCffJBjWRZP", + "id": "msg_0176GK1qFwwpVM59jDYiKPjN", "type": "message", "role": "assistant", "content": [ @@ -793,60 +77,63 @@ interactions: "ephemeral_1h_input_tokens": 0 }, "output_tokens": 5, - "service_tier": "standard" + "service_tier": "standard", + "inference_geo": "not_available" } } headers: CF-RAY: - - 9be0f7a98b01b734-EWR + - 9d6567b84d8509ae-EWR Connection: - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' Content-Type: - application/json Date: - - Wed, 14 Jan 2026 23:38:33 GMT + - Tue, 03 Mar 2026 03:02:57 GMT Server: - cloudflare Transfer-Encoding: - chunked X-Robots-Tag: - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 anthropic-ratelimit-input-tokens-limit: - - '30000' + - '450000' anthropic-ratelimit-input-tokens-remaining: - - '30000' + - '450000' anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:38:33Z' + - '2026-03-03T03:02:57Z' anthropic-ratelimit-output-tokens-limit: - - '8000' + - '90000' anthropic-ratelimit-output-tokens-remaining: - - '8000' + - '90000' anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:38:33Z' + - '2026-03-03T03:02:57Z' anthropic-ratelimit-requests-limit: - - '50' + - '1000' anthropic-ratelimit-requests-remaining: - - '49' + - '999' anthropic-ratelimit-requests-reset: - - '2026-01-14T23:38:32Z' + - '2026-03-03T03:02:56Z' anthropic-ratelimit-tokens-limit: - - '38000' + - '540000' anthropic-ratelimit-tokens-remaining: - - '38000' + - '540000' anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:38:33Z' + - '2026-03-03T03:02:57Z' cf-cache-status: - DYNAMIC content-length: - - '409' + - '441' request-id: - - req_011CX89jyLYwphKuArFEcRij + - req_011CYfQM6TP1iFTVWNrJQJcn strict-transport-security: - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding x-envoy-upstream-service-time: - - '1970' + - '1056' status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_content.yaml new file mode 100644 index 00000000000..3056b118225 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_content.yaml @@ -0,0 +1,140 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '117' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - '600' + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |- + { + "model": "claude-sonnet-4-20250514", + "id": "msg_01HZQzQu6SDuERFEAD5E2LLE", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Hello!" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 13, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 5, + "service_tier": "standard", + "inference_geo": "not_available" + } + } + headers: + CF-RAY: + - 9d6567bfdaa9c882-EWR + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Tue, 03 Mar 2026 03:02:58 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:02:58Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:02:58Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:02:57Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:02:58Z' + cf-cache-status: + - DYNAMIC + content-length: + - '441' + request-id: + - req_011CYfQMBeAfBDq653smhx2t + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '977' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_thinking_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_thinking_content.yaml new file mode 100644 index 00000000000..846cc9dca2c --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_thinking_content.yaml @@ -0,0 +1,149 @@ +interactions: +- request: + body: |- + { + "max_tokens": 16000, + "messages": [ + { + "role": "user", + "content": "What is 17*19? Think first." + } + ], + "model": "claude-sonnet-4-20250514", + "thinking": { + "type": "enabled", + "budget_tokens": 10000 + } + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '176' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - '600' + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |- + { + "model": "claude-sonnet-4-20250514", + "id": "msg_01NgMPJmYbigmhddjGchjPqH", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "thinking", + "thinking": "I need to calculate 17 \u00d7 19.\n\nLet me think about this step by step. I can use the standard multiplication method or look for patterns.\n\nOne approach is to use the fact that these are close to 20:\n17 \u00d7 19 = (20 - 3) \u00d7 (20 - 1)\n= 20\u00b2 - 20(1) - 20(3) + 3(1)\n= 400 - 20 - 60 + 3\n= 400 - 80 + 3\n= 323\n\nLet me double-check this with standard multiplication:\n 17\n\u00d7 19\n----\n 153 (17 \u00d7 9)\n170 (17 \u00d7 10)\n----\n323\n\nLet me verify the first line: 17 \u00d7 9\n17 \u00d7 9 = 17 \u00d7 (10 - 1) = 170 - 17 = 153 \u2713\n\nAnd 17 \u00d7 10 = 170 \u2713\n\nSo 153 + 170 = 323 \u2713\n\nBoth methods give me 323.", + "signature": "EuYFCkYICxgCKkDxKjCDNXmiJ72KrQXA/ugiHjqc/OWa4dnEXu4j+v4zmcZ4+W+F7rJXdg+tktg1xtGZ1q8YV8ks3D5z7qKU4wBcEgxLejbEBZAporXYjDAaDLjUh8AZqzczN1RQayIwf7KXei2iS5bdPbz+Uerq2AhvwjfWVyXrz4knPkQZPb1e6+BGrUfp1fEkYPxzUn4fKs0E4Y0nqE6xMzp9o1qOo3ZoBLGje2C8TMR82vE/9Ms2b4N088akwcPd6t7UkL3X5pb0FgXbdrNdhWOq66wnNZvLsVXsnRIoOdX2xculb5PJvQRgu+Pz8VXWwEsGZlmlhh/Zio+w1n6SELCpwahZPLdVGgKMssZ17B9Dc8SKldP6V8Yk4LtJLZDAnT0rbGVb92OUjEuYstDuBYwTur6cuQMUVZeNHQyLXybXDxGKxJ7yKndWOormD+LZOLveaeM+ttgpR/LH/lBaeLfaX0ft4ATSCGeZf2xysRCxUa6qco4Fs4BGU8e9RKC7ztT6SS/R2X9P15cD3fn9EfdH57CzvL3gBfrpSqcCnhV1DR9nlOZ5AJ8bfyOS4bPZN8bM6R4uPZmjUiItX7kmEZeUHt/GJQsdJAtb1/f/AGRXYyE/8/VL2yxB+q3PSsbVqSABqSAcLd9q5gl4nF9lkRhNcty8XznUjIanwCpjAJbLceE+Ml5nlYLDjaQhKEzwrmZnSZmCCjhi2BfN8hnBPh+SGuDAjP+J7aIOcY5LuJg836vdEwIRjSY73plwdf/h/RpEspc/uCspxMRQbCHigXwRpotTlAOHBJPYuoX5b5Ka2MpyUDAIBneDE44EQnMUJgv6LW6NrIOs2lp9FHMGEcfUZfnXK+zMQcq2wyHWrufNl/jPkj6BBQpflPZDNHudoPBm6WsIYgDTcrzam+zqLEUoH81zG9npzTzrRiwK2HPNfkoJk62eL67gJLE7jRK3v8r9IPVkPMYwiP0Yd6VRt6tZzjk1NhgB" + }, + { + "type": "text", + "text": "I need to calculate 17 \u00d7 19.\n\nLet me work through this step by step:\n\n17 \u00d7 19\n\nI can use the standard multiplication method:\n```\n 17\n\u00d7 19\n-----\n 153 (17 \u00d7 9)\n 170 (17 \u00d7 10, shifted)\n-----\n 323\n```\n\nLet me verify:\n- 17 \u00d7 9 = 153 \u2713\n- 17 \u00d7 10 = 170 \u2713 \n- 153 + 170 = 323 \u2713\n\nTherefore, 17 \u00d7 19 = 323." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 46, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 417, + "service_tier": "standard", + "inference_geo": "not_available" + } + } + headers: + CF-RAY: + - 9d65681d9c250fa4-EWR + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Tue, 03 Mar 2026 03:03:20 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:14Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:20Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:12Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:14Z' + cf-cache-status: + - DYNAMIC + content-length: + - '2421' + request-id: + - req_011CYfQNHwDY25u9A4Ss1BaU + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '7718' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_tool_use_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_tool_use_content.yaml new file mode 100644 index 00000000000..85d6bc4dd1c --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_captures_tool_use_content.yaml @@ -0,0 +1,168 @@ +interactions: +- request: + body: |- + { + "max_tokens": 256, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + } + ], + "model": "claude-sonnet-4-20250514", + "tool_choice": { + "type": "tool", + "name": "get_weather" + }, + "tools": [ + { + "name": "get_weather", + "description": "Get weather by city", + "input_schema": { + "type": "object", + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ] + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '334' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - '600' + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |- + { + "model": "claude-sonnet-4-20250514", + "id": "msg_01VkeD2PaERGgjekk84zPSwr", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_01UAcA2APHENDob6qJ8kmoaC", + "name": "get_weather", + "input": { + "city": "San Francisco" + }, + "caller": { + "type": "direct" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 386, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 34, + "service_tier": "standard", + "inference_geo": "not_available" + } + } + headers: + CF-RAY: + - 9d656813eddfae20-EWR + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Tue, 03 Mar 2026 03:03:11 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:11Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:11Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:10Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:11Z' + cf-cache-status: + - DYNAMIC + content-length: + - '550' + request-id: + - req_011CYfQNBARQegAkczG6kweQ + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '1256' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_event_only_no_content_in_span.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_event_only_no_content_in_span.yaml new file mode 100644 index 00000000000..eb8b7202993 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_event_only_no_content_in_span.yaml @@ -0,0 +1,140 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '117' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - '600' + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |- + { + "model": "claude-sonnet-4-20250514", + "id": "msg_01FaPr9xcPcSjcy2XAU85Pyj", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Hello!" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 13, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 5, + "service_tier": "standard", + "inference_geo": "not_available" + } + } + headers: + CF-RAY: + - 9d65687b3b23134a-EWR + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Tue, 03 Mar 2026 03:03:28 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:28Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:28Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:27Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:28Z' + cf-cache-status: + - DYNAMIC + content-length: + - '441' + request-id: + - req_011CYfQPPniijYhRkF7mjRn4 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '905' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_instrumentation_error_swallowed.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_instrumentation_error_swallowed.yaml new file mode 100644 index 00000000000..ef4a43e22a6 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_instrumentation_error_swallowed.yaml @@ -0,0 +1,138 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '131' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01NpSWjDnYM3G9wFsxNwNaBh","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello!"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0} + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":5} } + + event: message_stop + data: {"type":"message_stop"} + + headers: + CF-RAY: + - 9d6568736addb785-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:27 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:26Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:26Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:26Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:26Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1094' + request-id: + - req_011CYfQPJSkizN91DEN4ZUpZ + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '1001' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_stop_reason.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_stop_reason.yaml index 17e0fb87151..a314103663a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_stop_reason.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_stop_reason.yaml @@ -1,395 +1,4 @@ interactions: -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hi." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '114' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python - x-api-key: - - test_anthropic_api_key - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "id": "msg_04AGDUDYJgAACzvnptvVoYEL", - "type": "message", - "role": "assistant", - "model": "claude-3-5-sonnet-20241022", - "content": [ - { - "type": "text", - "text": "Hi!" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 10, - "output_tokens": 3 - } - } - headers: - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 15 Dec 2024 10:00:03 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - content-length: - - '340' - status: - code: 200 - message: OK -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hi." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '104' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "authentication_error", - "message": "invalid x-api-key" - }, - "request_id": "req_011CX88XA9TbQ5AUJfKb95H1" - } - headers: - CF-RAY: - - 9be0e035a86cc60f-EWR - Connection: - - keep-alive - Content-Length: - - '130' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:22:30 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88XA9TbQ5AUJfKb95H1 - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '14' - x-should-retry: - - 'false' - status: - code: 401 - message: Unauthorized -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hi." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '104' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "invalid_request_error", - "message": "Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits." - }, - "request_id": "req_011CX88Ze7X2Hzt93cQSJVwx" - } - headers: - CF-RAY: - - 9be0e1081e29cb6b-EWR - Connection: - - keep-alive - Content-Length: - - '234' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:23:04 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88Ze7X2Hzt93cQSJVwx - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '32' - x-should-retry: - - 'false' - status: - code: 400 - message: Bad Request -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Say hi." - } - ], - "model": "claude-sonnet-4-20250514" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '102' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "model": "claude-sonnet-4-20250514", - "id": "msg_0179PsyreizP7wUuiZek9cY1", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Hi! How are you doing today?" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 10, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 11, - "service_tier": "standard" - } - } - headers: - CF-RAY: - - 9be0f5f8dbb9c484-EWR - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:37:24 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - anthropic-ratelimit-input-tokens-limit: - - '30000' - anthropic-ratelimit-input-tokens-remaining: - - '30000' - anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:37:23Z' - anthropic-ratelimit-output-tokens-limit: - - '8000' - anthropic-ratelimit-output-tokens-remaining: - - '8000' - anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:37:24Z' - anthropic-ratelimit-requests-limit: - - '50' - anthropic-ratelimit-requests-remaining: - - '49' - anthropic-ratelimit-requests-reset: - - '2026-01-14T23:37:23Z' - anthropic-ratelimit-tokens-limit: - - '38000' - anthropic-ratelimit-tokens-remaining: - - '38000' - anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:37:23Z' - cf-cache-status: - - DYNAMIC - content-length: - - '432' - request-id: - - req_011CX89esEoi7zVpEaWsLZc8 - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '2140' - status: - code: 200 - message: OK - request: body: |- { @@ -448,7 +57,7 @@ interactions: string: |- { "model": "claude-sonnet-4-20250514", - "id": "msg_015tg8KmiFK3cef86zqT6mbU", + "id": "msg_012d8JRV176rPaczDFDxoDbT", "type": "message", "role": "assistant", "content": [ @@ -468,60 +77,63 @@ interactions: "ephemeral_1h_input_tokens": 0 }, "output_tokens": 11, - "service_tier": "standard" + "service_tier": "standard", + "inference_geo": "not_available" } } headers: CF-RAY: - - 9be0f7d4490ae55d-EWR + - 9d6567d9c9c5643e-EWR Connection: - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' Content-Type: - application/json Date: - - Wed, 14 Jan 2026 23:38:39 GMT + - Tue, 03 Mar 2026 03:03:02 GMT Server: - cloudflare Transfer-Encoding: - chunked X-Robots-Tag: - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 anthropic-ratelimit-input-tokens-limit: - - '30000' + - '450000' anthropic-ratelimit-input-tokens-remaining: - - '30000' + - '450000' anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:38:39Z' + - '2026-03-03T03:03:02Z' anthropic-ratelimit-output-tokens-limit: - - '8000' + - '90000' anthropic-ratelimit-output-tokens-remaining: - - '8000' + - '90000' anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:38:39Z' + - '2026-03-03T03:03:02Z' anthropic-ratelimit-requests-limit: - - '50' + - '1000' anthropic-ratelimit-requests-remaining: - - '49' + - '999' anthropic-ratelimit-requests-reset: - - '2026-01-14T23:38:39Z' + - '2026-03-03T03:03:01Z' anthropic-ratelimit-tokens-limit: - - '38000' + - '540000' anthropic-ratelimit-tokens-remaining: - - '38000' + - '540000' anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:38:39Z' + - '2026-03-03T03:03:02Z' cf-cache-status: - DYNAMIC content-length: - - '432' + - '464' request-id: - - req_011CX89kUUFsmSE8auY18PrD + - req_011CYfQMVM2pA3EVbN8Ja2sr strict-transport-security: - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding x-envoy-upstream-service-time: - - '1745' + - '1244' status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_stream_propagation_error.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_stream_propagation_error.yaml new file mode 100644 index 00000000000..f936fe4eeef --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_stream_propagation_error.yaml @@ -0,0 +1,138 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '131' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_014i5i2v6887MWQQjqctDRHo","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello!"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":5} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + CF-RAY: + - 9d656865ccea2ef5-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:24 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:23Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:23Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:23Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:23Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1132' + request-id: + - req_011CYfQP99QU9m2UtNA5BFZP + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '721' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming.yaml new file mode 100644 index 00000000000..7c2f521846c --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming.yaml @@ -0,0 +1,138 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '131' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01VY8H3oPFs4WWVnJXFDxNhU","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello."} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":5} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + CF-RAY: + - 9d6567ecfaf86dc6-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:05 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:04Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:04Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:04Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:04Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1126' + request-id: + - req_011CYfQMiWJUo29ePpD2ATbD + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '1037' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_aggregates_cache_tokens.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_aggregates_cache_tokens.yaml new file mode 100644 index 00000000000..1e2d98dd0a4 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_aggregates_cache_tokens.yaml @@ -0,0 +1,138 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '131' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01BpXsyrS2qCTuzQnTbLsB9w","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello!"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":5} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + CF-RAY: + - 9d65685e5bc3cc98-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:23 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:22Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:22Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:22Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:22Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1134' + request-id: + - req_011CYfQP44pFSHNJSnZKmaAe + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '957' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_captures_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_captures_content.yaml new file mode 100644 index 00000000000..f6599c15e4f --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_captures_content.yaml @@ -0,0 +1,138 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '131' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01VkmtVzTqckWr4Ym4746Lid","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello!"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":5} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + CF-RAY: + - 9d6567f53bf6c8b9-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:06 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:05Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:05Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:05Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:05Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1116' + request-id: + - req_011CYfQMpH4nmsRYY8zj6kCw + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '1028' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_delegates_response_attribute.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_delegates_response_attribute.yaml new file mode 100644 index 00000000000..372d88d8ff3 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_delegates_response_attribute.yaml @@ -0,0 +1,147 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hi." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '116' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01RJVipYo4aevccmbTqgpe2d","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":10,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hi"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"! How"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" are"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" you doing today?"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":10,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":11} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + CF-RAY: + - 9d656804cf5d0f84-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:09 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:08Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:08Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:08Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:08Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1540' + request-id: + - req_011CYfQMznqKRDJdKG8StgR4 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '741' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_iteration.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_iteration.yaml new file mode 100644 index 00000000000..1f530422566 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_iteration.yaml @@ -0,0 +1,147 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hi." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '116' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01AqjPamWtxvjFRhdM532SJo","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":10,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hi"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"! How"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" are"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" you doing today?"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":10,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":11} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + CF-RAY: + - 9d6567fd7d44c269-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:07 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:07Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:07Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:07Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:07Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1519' + request-id: + - req_011CYfQMuohKD5gG9juMpkR9 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '784' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_user_exception.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_user_exception.yaml new file mode 100644 index 00000000000..38dd8a1e58d --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_streaming_user_exception.yaml @@ -0,0 +1,138 @@ +interactions: +- request: + body: |- + { + "max_tokens": 100, + "messages": [ + { + "role": "user", + "content": "Say hello in one word." + } + ], + "model": "claude-sonnet-4-20250514", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + anthropic-version: + - '2023-06-01' + connection: + - keep-alive + content-length: + - '131' + content-type: + - application/json + host: + - api.anthropic.com + user-agent: + - Anthropic/Python 0.75.0 + x-api-key: + - test_anthropic_api_key + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 0.75.0 + x-stainless-read-timeout: + - '600' + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.9.6 + x-stainless-timeout: + - NOT_GIVEN + method: POST + uri: https://api.anthropic.com/v1/messages + response: + body: + string: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01KTDb2NA7N8ZMdCVJi55gsc","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello!"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":13,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":5} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + CF-RAY: + - 9d65686baf371a38-EWR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Tue, 03 Mar 2026 03:03:25 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Robots-Tag: + - none + anthropic-ratelimit-input-tokens-limit: + - '450000' + anthropic-ratelimit-input-tokens-remaining: + - '450000' + anthropic-ratelimit-input-tokens-reset: + - '2026-03-03T03:03:24Z' + anthropic-ratelimit-output-tokens-limit: + - '90000' + anthropic-ratelimit-output-tokens-remaining: + - '90000' + anthropic-ratelimit-output-tokens-reset: + - '2026-03-03T03:03:24Z' + anthropic-ratelimit-requests-limit: + - '1000' + anthropic-ratelimit-requests-remaining: + - '999' + anthropic-ratelimit-requests-reset: + - '2026-03-03T03:03:24Z' + anthropic-ratelimit-tokens-limit: + - '540000' + anthropic-ratelimit-tokens-remaining: + - '540000' + anthropic-ratelimit-tokens-reset: + - '2026-03-03T03:03:24Z' + cf-cache-status: + - DYNAMIC + content-length: + - '1125' + request-id: + - req_011CYfQPDB12HAd3CZ3B6udD + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding + x-envoy-upstream-service-time: + - '962' + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_token_usage.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_token_usage.yaml index e6f90a09512..f49d27e0ec8 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_token_usage.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_token_usage.yaml @@ -1,395 +1,4 @@ interactions: -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Count to 5." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '118' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python - x-api-key: - - test_anthropic_api_key - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "id": "msg_03ZGDUDYJgAACzvnptvVoYEL", - "type": "message", - "role": "assistant", - "model": "claude-3-5-sonnet-20241022", - "content": [ - { - "type": "text", - "text": "1, 2, 3, 4, 5" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 12, - "output_tokens": 14 - } - } - headers: - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 15 Dec 2024 10:00:02 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - content-length: - - '355' - status: - code: 200 - message: OK -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Count to 5." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '108' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "authentication_error", - "message": "invalid x-api-key" - }, - "request_id": "req_011CX88X9HN93DBTEXsjo9DZ" - } - headers: - CF-RAY: - - 9be0e0346f01a0f4-EWR - Connection: - - keep-alive - Content-Length: - - '130' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:22:30 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88X9HN93DBTEXsjo9DZ - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '11' - x-should-retry: - - 'false' - status: - code: 401 - message: Unauthorized -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Count to 5." - } - ], - "model": "claude-3-5-sonnet-20241022" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '108' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "invalid_request_error", - "message": "Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits." - }, - "request_id": "req_011CX88Zd4WpWvH6NbSKLd4T" - } - headers: - CF-RAY: - - 9be0e1068d28f9a9-EWR - Connection: - - keep-alive - Content-Length: - - '234' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:23:04 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88Zd4WpWvH6NbSKLd4T - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '23' - x-should-retry: - - 'false' - status: - code: 400 - message: Bad Request -- request: - body: |- - { - "max_tokens": 100, - "messages": [ - { - "role": "user", - "content": "Count to 5." - } - ], - "model": "claude-sonnet-4-20250514" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '106' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "model": "claude-sonnet-4-20250514", - "id": "msg_01ASpi9ptEqzyzyCGk3aB1tr", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "1\n2\n3\n4\n5" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 12, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 13, - "service_tier": "standard" - } - } - headers: - CF-RAY: - - 9be0f5e96d19cc98-EWR - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:37:21 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - anthropic-ratelimit-input-tokens-limit: - - '30000' - anthropic-ratelimit-input-tokens-remaining: - - '30000' - anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:37:21Z' - anthropic-ratelimit-output-tokens-limit: - - '8000' - anthropic-ratelimit-output-tokens-remaining: - - '8000' - anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:37:21Z' - anthropic-ratelimit-requests-limit: - - '50' - anthropic-ratelimit-requests-remaining: - - '49' - anthropic-ratelimit-requests-reset: - - '2026-01-14T23:37:20Z' - anthropic-ratelimit-tokens-limit: - - '38000' - anthropic-ratelimit-tokens-remaining: - - '38000' - anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:37:21Z' - cf-cache-status: - - DYNAMIC - content-length: - - '417' - request-id: - - req_011CX89egfZS3S8npjMnb4jb - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '2246' - status: - code: 200 - message: OK - request: body: |- { @@ -448,7 +57,7 @@ interactions: string: |- { "model": "claude-sonnet-4-20250514", - "id": "msg_01JFQS8RhcxvidJNQvmANwSp", + "id": "msg_015sFGNKbMjgUZs7UU75pU6d", "type": "message", "role": "assistant", "content": [ @@ -468,60 +77,63 @@ interactions: "ephemeral_1h_input_tokens": 0 }, "output_tokens": 17, - "service_tier": "standard" + "service_tier": "standard", + "inference_geo": "not_available" } } headers: CF-RAY: - - 9be0f7c51d21c62c-EWR + - 9d6567cfabc719c7-EWR Connection: - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' Content-Type: - application/json Date: - - Wed, 14 Jan 2026 23:38:37 GMT + - Tue, 03 Mar 2026 03:03:01 GMT Server: - cloudflare Transfer-Encoding: - chunked X-Robots-Tag: - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 anthropic-ratelimit-input-tokens-limit: - - '30000' + - '450000' anthropic-ratelimit-input-tokens-remaining: - - '30000' + - '450000' anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:38:36Z' + - '2026-03-03T03:03:00Z' anthropic-ratelimit-output-tokens-limit: - - '8000' + - '90000' anthropic-ratelimit-output-tokens-remaining: - - '8000' + - '90000' anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:38:38Z' + - '2026-03-03T03:03:01Z' anthropic-ratelimit-requests-limit: - - '50' + - '1000' anthropic-ratelimit-requests-remaining: - - '49' + - '999' anthropic-ratelimit-requests-reset: - - '2026-01-14T23:38:36Z' + - '2026-03-03T03:02:59Z' anthropic-ratelimit-tokens-limit: - - '38000' + - '540000' anthropic-ratelimit-tokens-remaining: - - '38000' + - '540000' anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:38:36Z' + - '2026-03-03T03:03:00Z' cf-cache-status: - DYNAMIC content-length: - - '417' + - '449' request-id: - - req_011CX89kJ5gA2k39mva9DeiB + - req_011CYfQMNSoikmPWgmgcCCJb strict-transport-security: - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding x-envoy-upstream-service-time: - - '2244' + - '1464' status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_with_all_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_with_all_params.yaml index b63b5b56da3..6fad0a4c908 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_with_all_params.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/cassettes/test_sync_messages_create_with_all_params.yaml @@ -1,419 +1,4 @@ interactions: -- request: - body: |- - { - "max_tokens": 50, - "messages": [ - { - "role": "user", - "content": "Say hello." - } - ], - "model": "claude-3-5-sonnet-20241022", - "stop_sequences": [ - "STOP" - ], - "temperature": 0.7, - "top_k": 40, - "top_p": 0.9 - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '200' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python - x-api-key: - - test_anthropic_api_key - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "id": "msg_02YGDUDYJgAACzvnptvVoYEL", - "type": "message", - "role": "assistant", - "model": "claude-3-5-sonnet-20241022", - "content": [ - { - "type": "text", - "text": "Hello! How can I help you today?" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 10, - "output_tokens": 10 - } - } - headers: - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 15 Dec 2024 10:00:01 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - content-length: - - '380' - status: - code: 200 - message: OK -- request: - body: |- - { - "max_tokens": 50, - "messages": [ - { - "role": "user", - "content": "Say hello." - } - ], - "model": "claude-3-5-sonnet-20241022", - "stop_sequences": [ - "STOP" - ], - "temperature": 0.7, - "top_k": 40, - "top_p": 0.9 - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '173' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "authentication_error", - "message": "invalid x-api-key" - }, - "request_id": "req_011CX88X8R2SNXCvHpf8jdxa" - } - headers: - CF-RAY: - - 9be0e0331fe3effa-EWR - Connection: - - keep-alive - Content-Length: - - '130' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:22:30 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88X8R2SNXCvHpf8jdxa - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '14' - x-should-retry: - - 'false' - status: - code: 401 - message: Unauthorized -- request: - body: |- - { - "max_tokens": 50, - "messages": [ - { - "role": "user", - "content": "Say hello." - } - ], - "model": "claude-3-5-sonnet-20241022", - "stop_sequences": [ - "STOP" - ], - "temperature": 0.7, - "top_k": 40, - "top_p": 0.9 - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '173' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "type": "error", - "error": { - "type": "invalid_request_error", - "message": "Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits." - }, - "request_id": "req_011CX88Zc1kwbPkJkhghetKz" - } - headers: - CF-RAY: - - 9be0e10508204ba5-EWR - Connection: - - keep-alive - Content-Length: - - '234' - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:23:03 GMT - Server: - - cloudflare - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - cf-cache-status: - - DYNAMIC - request-id: - - req_011CX88Zc1kwbPkJkhghetKz - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '31' - x-should-retry: - - 'false' - status: - code: 400 - message: Bad Request -- request: - body: |- - { - "max_tokens": 50, - "messages": [ - { - "role": "user", - "content": "Say hello." - } - ], - "model": "claude-sonnet-4-20250514", - "stop_sequences": [ - "STOP" - ], - "temperature": 0.7, - "top_k": 40, - "top_p": 0.9 - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - anthropic-version: - - '2023-06-01' - connection: - - keep-alive - content-length: - - '171' - content-type: - - application/json - host: - - api.anthropic.com - user-agent: - - Anthropic/Python 0.75.0 - x-api-key: - - test_anthropic_api_key - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 0.75.0 - x-stainless-read-timeout: - - '600' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.9.6 - x-stainless-timeout: - - '600' - method: POST - uri: https://api.anthropic.com/v1/messages - response: - body: - string: |- - { - "model": "claude-sonnet-4-20250514", - "id": "msg_01Nf6xgm48TeELiSicTA83cX", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Hello! How are you doing today?" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 10, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 11, - "service_tier": "standard" - } - } - headers: - CF-RAY: - - 9be0f5db9b8110f3-EWR - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 14 Jan 2026 23:37:19 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Robots-Tag: - - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 - anthropic-ratelimit-input-tokens-limit: - - '30000' - anthropic-ratelimit-input-tokens-remaining: - - '30000' - anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:37:18Z' - anthropic-ratelimit-output-tokens-limit: - - '8000' - anthropic-ratelimit-output-tokens-remaining: - - '8000' - anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:37:19Z' - anthropic-ratelimit-requests-limit: - - '50' - anthropic-ratelimit-requests-remaining: - - '49' - anthropic-ratelimit-requests-reset: - - '2026-01-14T23:37:18Z' - anthropic-ratelimit-tokens-limit: - - '38000' - anthropic-ratelimit-tokens-remaining: - - '38000' - anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:37:18Z' - cf-cache-status: - - DYNAMIC - content-length: - - '435' - request-id: - - req_011CX89eXCYZvbfUZDzWQK3e - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-envoy-upstream-service-time: - - '1953' - status: - code: 200 - message: OK - request: body: |- { @@ -478,13 +63,13 @@ interactions: string: |- { "model": "claude-sonnet-4-20250514", - "id": "msg_015XXNApQAi4ZgazLmEDHne6", + "id": "msg_015vKsHVeGGXxG7Q49sUsfwG", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "Hello! How are you doing today?" + "text": "Hello! It's nice to meet you. How are you doing today?" } ], "stop_reason": "end_turn", @@ -497,61 +82,64 @@ interactions: "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 11, - "service_tier": "standard" + "output_tokens": 18, + "service_tier": "standard", + "inference_geo": "not_available" } } headers: CF-RAY: - - 9be0f7b73af7c269-EWR + - 9d6567c6f9f51016-EWR Connection: - keep-alive + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' Content-Type: - application/json Date: - - Wed, 14 Jan 2026 23:38:35 GMT + - Tue, 03 Mar 2026 03:02:59 GMT Server: - cloudflare Transfer-Encoding: - chunked X-Robots-Tag: - none - anthropic-organization-id: - - 455ea6be-bd92-4199-83ec-0c6b39c5c169 anthropic-ratelimit-input-tokens-limit: - - '30000' + - '450000' anthropic-ratelimit-input-tokens-remaining: - - '30000' + - '450000' anthropic-ratelimit-input-tokens-reset: - - '2026-01-14T23:38:35Z' + - '2026-03-03T03:02:59Z' anthropic-ratelimit-output-tokens-limit: - - '8000' + - '90000' anthropic-ratelimit-output-tokens-remaining: - - '8000' + - '90000' anthropic-ratelimit-output-tokens-reset: - - '2026-01-14T23:38:35Z' + - '2026-03-03T03:02:59Z' anthropic-ratelimit-requests-limit: - - '50' + - '1000' anthropic-ratelimit-requests-remaining: - - '49' + - '999' anthropic-ratelimit-requests-reset: - - '2026-01-14T23:38:34Z' + - '2026-03-03T03:02:58Z' anthropic-ratelimit-tokens-limit: - - '38000' + - '540000' anthropic-ratelimit-tokens-remaining: - - '38000' + - '540000' anthropic-ratelimit-tokens-reset: - - '2026-01-14T23:38:35Z' + - '2026-03-03T03:02:59Z' cf-cache-status: - DYNAMIC content-length: - - '435' + - '490' request-id: - - req_011CX89k8aBRkvFFLPZSBSrX + - req_011CYfQMGWs6c2NPKvC1SwEp strict-transport-security: - max-age=31536000; includeSubDomains; preload + vary: + - Accept-Encoding x-envoy-upstream-service-time: - - '1955' + - '1225' status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/conftest.py index 9f660d1fd43..c9573d82518 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/conftest.py @@ -22,6 +22,10 @@ import yaml from anthropic import Anthropic +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk._logs.export import ( @@ -37,6 +41,7 @@ ) from opentelemetry.util.genai.environment_variables import ( OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, + OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT, ) @@ -115,8 +120,12 @@ def vcr_config(): @pytest.fixture(scope="function") def instrument_no_content(tracer_provider, logger_provider, meter_provider): """Instrument Anthropic without content capture.""" + _OpenTelemetrySemanticConventionStability._initialized = False os.environ.update( - {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "False"} + { + OTEL_SEMCONV_STABILITY_OPT_IN: "stable", + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "NO_CONTENT", + } ) instrumentor = AnthropicInstrumentor() @@ -126,16 +135,26 @@ def instrument_no_content(tracer_provider, logger_provider, meter_provider): meter_provider=meter_provider, ) - yield instrumentor - os.environ.pop(OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None) - instrumentor.uninstrument() + try: + yield instrumentor + finally: + os.environ.pop( + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None + ) + os.environ.pop(OTEL_SEMCONV_STABILITY_OPT_IN, None) + instrumentor.uninstrument() + _OpenTelemetrySemanticConventionStability._initialized = False @pytest.fixture(scope="function") def instrument_with_content(tracer_provider, logger_provider, meter_provider): """Instrument Anthropic with content capture enabled.""" + _OpenTelemetrySemanticConventionStability._initialized = False os.environ.update( - {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"} + { + OTEL_SEMCONV_STABILITY_OPT_IN: "gen_ai_latest_experimental", + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "SPAN_ONLY", + } ) instrumentor = AnthropicInstrumentor() instrumentor.instrument( @@ -144,9 +163,45 @@ def instrument_with_content(tracer_provider, logger_provider, meter_provider): meter_provider=meter_provider, ) - yield instrumentor - os.environ.pop(OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None) - instrumentor.uninstrument() + try: + yield instrumentor + finally: + os.environ.pop( + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None + ) + os.environ.pop(OTEL_SEMCONV_STABILITY_OPT_IN, None) + instrumentor.uninstrument() + _OpenTelemetrySemanticConventionStability._initialized = False + + +@pytest.fixture(scope="function") +def instrument_event_only(tracer_provider, logger_provider, meter_provider): + """Instrument Anthropic with EVENT_ONLY content capture.""" + _OpenTelemetrySemanticConventionStability._initialized = False + os.environ.update( + { + OTEL_SEMCONV_STABILITY_OPT_IN: "gen_ai_latest_experimental", + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "EVENT_ONLY", + OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT: "true", + } + ) + instrumentor = AnthropicInstrumentor() + instrumentor.instrument( + tracer_provider=tracer_provider, + logger_provider=logger_provider, + meter_provider=meter_provider, + ) + + try: + yield instrumentor + finally: + os.environ.pop( + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None + ) + os.environ.pop(OTEL_SEMCONV_STABILITY_OPT_IN, None) + os.environ.pop(OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT, None) + instrumentor.uninstrument() + _OpenTelemetrySemanticConventionStability._initialized = False @pytest.fixture @@ -230,6 +285,16 @@ def fixture_vcr(vcr): return vcr +_SCRUBBED_RESPONSE_HEADERS = frozenset( + { + "anthropic-organization-id", + } +) + + def scrub_response_headers(response): - """Scrub sensitive response headers.""" + """Scrub sensitive headers from recorded responses.""" + headers = response.get("headers", {}) + for header in _SCRUBBED_RESPONSE_HEADERS: + headers.pop(header, None) return response diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/requirements.oldest.txt index b962a025550..0b77b1a7cb4 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/requirements.oldest.txt @@ -16,8 +16,7 @@ # the oldest supported version of external dependencies. -e util/opentelemetry-util-genai -anthropic==0.16.0 -httpx>=0.25.2,<0.28.0 # Pin to version compatible with anthropic 0.16.0 (proxies arg removed in 0.28) +anthropic==0.51.0 pytest==7.4.4 pytest-vcr==1.0.2 pytest-asyncio==0.21.0 diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_sync_messages.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_sync_messages.py index f656f61eeff..6bce6f2e162 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_sync_messages.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_sync_messages.py @@ -14,10 +14,23 @@ """Tests for sync Messages.create instrumentation.""" +import inspect +import json +import os +from pathlib import Path + import pytest from anthropic import Anthropic, APIConnectionError, NotFoundError +from anthropic.resources.messages import Messages as _Messages from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor +from opentelemetry.instrumentation.anthropic.messages_extractors import ( + GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, + GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, +) +from opentelemetry.instrumentation.anthropic.wrappers import ( + MessagesStreamWrapper, +) from opentelemetry.semconv._incubating.attributes import ( error_attributes as ErrorAttributes, ) @@ -28,8 +41,32 @@ server_attributes as ServerAttributes, ) +# Detect whether the installed anthropic SDK supports tools / thinking params. +# Older SDK versions (e.g. 0.16.0) do not accept these keyword arguments. +_create_params = set(inspect.signature(_Messages.create).parameters) +_has_tools_param = "tools" in _create_params +_has_thinking_param = "thinking" in _create_params + + +def normalize_stop_reason(stop_reason): + """Map Anthropic stop reasons to GenAI semconv values.""" + return { + "end_turn": "stop", + "stop_sequence": "stop", + "max_tokens": "length", + "tool_use": "tool_calls", + }.get(stop_reason, stop_reason) -def assert_span_attributes( + +def expected_input_tokens(usage): + """Compute semconv input tokens from Anthropic usage.""" + base = getattr(usage, "input_tokens", 0) or 0 + cache_creation = getattr(usage, "cache_creation_input_tokens", 0) or 0 + cache_read = getattr(usage, "cache_read_input_tokens", 0) or 0 + return base + cache_creation + cache_read + + +def assert_span_attributes( # pylint: disable=too-many-arguments span, request_model, response_id=None, @@ -86,6 +123,27 @@ def assert_span_attributes( ) +def _load_span_messages(span, attribute): + value = span.attributes.get(attribute) + assert value is not None + assert isinstance(value, str) + parsed = json.loads(value) + assert isinstance(parsed, list) + return parsed + + +def _skip_if_cassette_missing_and_no_real_key(request): + cassette_path = ( + Path(__file__).parent / "cassettes" / f"{request.node.name}.yaml" + ) + api_key = os.getenv("ANTHROPIC_API_KEY") + if not cassette_path.exists() and api_key == "test_anthropic_api_key": + pytest.skip( + f"Cassette {cassette_path.name} is missing. " + "Set a real ANTHROPIC_API_KEY to record it." + ) + + @pytest.mark.vcr() def test_sync_messages_create_basic( span_exporter, anthropic_client, instrument_no_content @@ -108,11 +166,42 @@ def test_sync_messages_create_basic( request_model=model, response_id=response.id, response_model=response.model, - input_tokens=response.usage.input_tokens, + input_tokens=expected_input_tokens(response.usage), output_tokens=response.usage.output_tokens, - finish_reasons=[response.stop_reason], + finish_reasons=[normalize_stop_reason(response.stop_reason)], + ) + + +@pytest.mark.vcr() +def test_sync_messages_create_captures_content( + span_exporter, anthropic_client, instrument_with_content +): + """Test content capture on non-streaming create.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + + input_messages = _load_span_messages( + span, GenAIAttributes.GEN_AI_INPUT_MESSAGES + ) + output_messages = _load_span_messages( + span, GenAIAttributes.GEN_AI_OUTPUT_MESSAGES ) + assert input_messages[0]["role"] == "user" + assert input_messages[0]["parts"][0]["type"] == "text" + assert output_messages[0]["role"] == "assistant" + assert output_messages[0]["parts"][0]["type"] == "text" + @pytest.mark.vcr() def test_sync_messages_create_with_all_params( @@ -165,10 +254,9 @@ def test_sync_messages_create_token_usage( span = spans[0] assert GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS in span.attributes assert GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS in span.attributes - assert ( - span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] - == response.usage.input_tokens - ) + assert span.attributes[ + GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS + ] == expected_input_tokens(response.usage) assert ( span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response.usage.output_tokens @@ -195,7 +283,7 @@ def test_sync_messages_create_stop_reason( span = spans[0] # Anthropic's stop_reason should be wrapped in a tuple (OTel converts lists) assert span.attributes[GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS] == ( - response.stop_reason, + normalize_stop_reason(response.stop_reason), ) @@ -300,3 +388,554 @@ def test_multiple_instrument_uninstrument_cycles( meter_provider=meter_provider, ) instrumentor.uninstrument() + + +@pytest.mark.vcr() +def test_sync_messages_create_streaming( # pylint: disable=too-many-locals + span_exporter, anthropic_client, instrument_no_content +): + """Test streaming message creation produces correct span.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + # Collect response data from stream + response_text = "" + response_id = None + response_model = None + stop_reason = None + input_tokens = None + output_tokens = None + + with anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + ) as stream: + for chunk in stream: + # Extract data from chunks for assertion + if chunk.type == "message_start": + message = getattr(chunk, "message", None) + if message: + response_id = getattr(message, "id", None) + response_model = getattr(message, "model", None) + usage = getattr(message, "usage", None) + if usage: + input_tokens = getattr(usage, "input_tokens", None) + elif chunk.type == "content_block_delta": + delta = getattr(chunk, "delta", None) + if delta and hasattr(delta, "text"): + response_text += delta.text + elif chunk.type == "message_delta": + delta = getattr(chunk, "delta", None) + if delta: + stop_reason = getattr(delta, "stop_reason", None) + usage = getattr(chunk, "usage", None) + if usage: + output_tokens = getattr(usage, "output_tokens", None) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + + assert_span_attributes( + spans[0], + request_model=model, + response_id=response_id, + response_model=response_model, + input_tokens=input_tokens, + output_tokens=output_tokens, + finish_reasons=[normalize_stop_reason(stop_reason)] + if stop_reason + else None, + ) + + +@pytest.mark.vcr() +def test_sync_messages_create_streaming_captures_content( + span_exporter, anthropic_client, instrument_with_content +): + """Test content capture on create(stream=True).""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + with anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + ) as stream: + for _ in stream: + pass + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + + input_messages = _load_span_messages( + span, GenAIAttributes.GEN_AI_INPUT_MESSAGES + ) + output_messages = _load_span_messages( + span, GenAIAttributes.GEN_AI_OUTPUT_MESSAGES + ) + assert input_messages[0]["role"] == "user" + assert output_messages[0]["role"] == "assistant" + assert output_messages[0]["parts"] + + +@pytest.mark.vcr() +def test_sync_messages_create_streaming_iteration( + span_exporter, anthropic_client, instrument_no_content +): + """Test streaming with direct iteration (without context manager).""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hi."}] + + stream = anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + ) + + # Consume the stream by iterating + chunks = list(stream) + assert len(chunks) > 0 + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + + span = spans[0] + assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] == model + # Verify span has response attributes from streaming + assert GenAIAttributes.GEN_AI_RESPONSE_ID in span.attributes + assert GenAIAttributes.GEN_AI_RESPONSE_MODEL in span.attributes + + +@pytest.mark.vcr() +def test_sync_messages_create_streaming_delegates_response_attribute( + request, anthropic_client, instrument_no_content +): + """Stream wrapper should expose attributes from the wrapped stream.""" + _skip_if_cassette_missing_and_no_real_key(request) + + stream = anthropic_client.messages.create( + model="claude-sonnet-4-20250514", + max_tokens=100, + messages=[{"role": "user", "content": "Say hi."}], + stream=True, + ) + + # `response` exists on Anthropic Stream and should be reachable on wrapper. + assert stream.response is not None + assert stream.response.status_code == 200 + assert stream.response.headers.get("request-id") is not None + stream.close() + + +def test_sync_messages_create_streaming_connection_error( + span_exporter, instrument_no_content +): + """Test that connection errors during streaming are handled correctly.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Hello"}] + + # Create client with invalid endpoint + client = Anthropic(base_url="http://localhost:9999") + + with pytest.raises(APIConnectionError): + client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + timeout=0.1, + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + + span = spans[0] + assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] == model + assert ErrorAttributes.ERROR_TYPE in span.attributes + assert "APIConnectionError" in span.attributes[ErrorAttributes.ERROR_TYPE] + + +@pytest.mark.vcr() +@pytest.mark.skipif( + not _has_tools_param, + reason="anthropic SDK too old to support 'tools' parameter", +) +def test_sync_messages_create_captures_tool_use_content( + request, span_exporter, anthropic_client, instrument_with_content +): + """Test that tool_use blocks are captured as tool_call parts.""" + _skip_if_cassette_missing_and_no_real_key(request) + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "What is the weather in SF?"}] + + anthropic_client.messages.create( + model=model, + max_tokens=256, + messages=messages, + tools=[ + { + "name": "get_weather", + "description": "Get weather by city", + "input_schema": { + "type": "object", + "properties": {"city": {"type": "string"}}, + "required": ["city"], + }, + } + ], + tool_choice={"type": "tool", "name": "get_weather"}, + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + output_messages = _load_span_messages( + span, GenAIAttributes.GEN_AI_OUTPUT_MESSAGES + ) + + assert any( + part.get("type") == "tool_call" + for message in output_messages + for part in message.get("parts", []) + ) + + +@pytest.mark.vcr() +@pytest.mark.skipif( + not _has_thinking_param, + reason="anthropic SDK too old to support 'thinking' parameter", +) +def test_sync_messages_create_captures_thinking_content( + request, span_exporter, anthropic_client, instrument_with_content +): + """Test that thinking blocks are captured as reasoning parts.""" + _skip_if_cassette_missing_and_no_real_key(request) + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "What is 17*19? Think first."}] + + anthropic_client.messages.create( + model=model, + max_tokens=16000, + messages=messages, + thinking={"type": "enabled", "budget_tokens": 10000}, + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + output_messages = _load_span_messages( + span, GenAIAttributes.GEN_AI_OUTPUT_MESSAGES + ) + + assert any( + part.get("type") == "reasoning" + for message in output_messages + for part in message.get("parts", []) + ) + + +@pytest.mark.vcr() +def test_stream_wrapper_finalize_idempotent( # pylint: disable=too-many-locals + span_exporter, + anthropic_client, + instrument_no_content, +): + """Fully consumed stream plus explicit close should still yield one span.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + stream = anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + ) + + response_id = None + response_model = None + stop_reason = None + input_tokens = None + output_tokens = None + + # Consume the stream fully, then call close() to verify idempotent finalization. + for chunk in stream: + if chunk.type == "message_start": + message = getattr(chunk, "message", None) + if message: + response_id = getattr(message, "id", None) + response_model = getattr(message, "model", None) + usage = getattr(message, "usage", None) + if usage: + input_tokens = expected_input_tokens(usage) + elif chunk.type == "message_delta": + delta = getattr(chunk, "delta", None) + if delta: + stop_reason = getattr(delta, "stop_reason", None) + usage = getattr(chunk, "usage", None) + if usage: + output_tokens = getattr(usage, "output_tokens", None) + input_tokens = expected_input_tokens(usage) + + stream.close() + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + assert_span_attributes( + spans[0], + request_model=model, + response_id=response_id, + response_model=response_model, + input_tokens=input_tokens, + output_tokens=output_tokens, + finish_reasons=[normalize_stop_reason(stop_reason)] + if stop_reason + else None, + ) + + +@pytest.mark.vcr() +def test_sync_messages_create_aggregates_cache_tokens( + span_exporter, anthropic_client, instrument_no_content +): + """Non-streaming response with non-zero cache tokens aggregates correctly.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + response = anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + + assert GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS in span.attributes + assert GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS in span.attributes + assert span.attributes[ + GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS + ] == expected_input_tokens(response.usage) + assert ( + span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + == response.usage.output_tokens + ) + cache_creation = getattr(response.usage, "cache_creation_input_tokens", 0) + cache_read = getattr(response.usage, "cache_read_input_tokens", 0) + assert ( + span.attributes[GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS] + == cache_creation + ) + assert span.attributes[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] == cache_read + + +@pytest.mark.vcr() +def test_sync_messages_create_streaming_aggregates_cache_tokens( + span_exporter, anthropic_client, instrument_no_content +): + """Streaming response with non-zero cache tokens aggregates correctly.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + input_tokens = None + output_tokens = None + cache_creation = None + cache_read = None + + with anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + ) as stream: + for chunk in stream: + if chunk.type == "message_delta": + usage = getattr(chunk, "usage", None) + if usage: + input_tokens = expected_input_tokens(usage) + output_tokens = getattr(usage, "output_tokens", None) + cache_creation = getattr( + usage, "cache_creation_input_tokens", None + ) + cache_read = getattr( + usage, "cache_read_input_tokens", None + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + + assert GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS in span.attributes + assert GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS in span.attributes + assert ( + span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] + == input_tokens + ) + assert ( + span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + == output_tokens + ) + assert ( + span.attributes[GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS] + == cache_creation + ) + assert span.attributes[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] == cache_read + + +@pytest.mark.vcr() +def test_sync_messages_create_stream_propagation_error( + span_exporter, anthropic_client, instrument_no_content, monkeypatch +): + """Mid-stream errors from the underlying iterator must propagate and record error on span.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + stream = anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + ) + + # Wrap the underlying stream so we inject an iteration error but still + # delegate close()/other behavior to the real stream. + class ErrorInjectingStreamDelegate: + def __init__(self, inner): + self._inner = inner + self._count = 0 + + def __iter__(self): + return self + + def __next__(self): + # Fail after yielding one chunk so this exercises a mid-stream error. + if self._count == 1: + raise ConnectionError("connection reset during stream") + self._count += 1 + return next(self._inner) + + def close(self): + return self._inner.close() + + def __getattr__(self, name): + return getattr(self._inner, name) + + monkeypatch.setattr( + stream, "_stream", ErrorInjectingStreamDelegate(stream._stream) + ) + + with pytest.raises( + ConnectionError, match="connection reset during stream" + ): + with stream: + for _ in stream: + pass + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] == model + assert span.attributes[ErrorAttributes.ERROR_TYPE] == "ConnectionError" + + +@pytest.mark.vcr() +def test_sync_messages_create_streaming_user_exception( + span_exporter, anthropic_client, instrument_no_content +): + """Test that user raised exceptions are propagated.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + with pytest.raises(ValueError, match="User raised exception"): + with anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + ) as stream: + for _ in stream: + raise ValueError("User raised exception") + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] == model + assert span.attributes[ErrorAttributes.ERROR_TYPE] == "ValueError" + + +@pytest.mark.vcr() +def test_sync_messages_create_instrumentation_error_swallowed( + span_exporter, anthropic_client, instrument_no_content, monkeypatch +): + """Instrumentation errors in _process_chunk must not propagate to user code.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + def exploding_process_chunk(self, chunk): + raise RuntimeError("instrumentation bug") + + monkeypatch.setattr( + MessagesStreamWrapper, "_process_chunk", exploding_process_chunk + ) + + with anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + stream=True, + ) as stream: + chunks = list(stream) + + assert len(chunks) > 0 + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] == model + assert ErrorAttributes.ERROR_TYPE not in span.attributes + + +# ============================================================================= +# Tests for EVENT_ONLY content capture mode +# ============================================================================= + + +@pytest.mark.vcr() +def test_sync_messages_create_event_only_no_content_in_span( + span_exporter, log_exporter, anthropic_client, instrument_event_only +): + """Test that EVENT_ONLY mode does not capture content in span attributes + but does emit a log event with the content.""" + model = "claude-sonnet-4-20250514" + messages = [{"role": "user", "content": "Say hello in one word."}] + + anthropic_client.messages.create( + model=model, + max_tokens=100, + messages=messages, + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + + # Content should NOT be in span attributes under EVENT_ONLY + assert GenAIAttributes.GEN_AI_INPUT_MESSAGES not in span.attributes + assert GenAIAttributes.GEN_AI_OUTPUT_MESSAGES not in span.attributes + + # Basic span attributes should still be present + assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] == model + assert GenAIAttributes.GEN_AI_RESPONSE_MODEL in span.attributes + assert GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS in span.attributes + assert GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS in span.attributes + + # A log event should have been emitted with the content + logs = log_exporter.get_finished_logs() + assert len(logs) == 1 + log_record = logs[0].log_record + assert log_record.event_name == "gen_ai.client.inference.operation.details" diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/utils.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/utils.py index 616d9ab4713..8b6c5e8a2ac 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/utils.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/utils.py @@ -111,6 +111,18 @@ def should_emit_event() -> bool: return False +def should_capture_content_on_spans_in_experimental_mode() -> bool: + """Return True when content conversion should be performed.""" + if not is_experimental_mode(): + return False + mode = get_content_capturing_mode() + if mode == ContentCapturingMode.NO_CONTENT: + return False + if mode == ContentCapturingMode.EVENT_ONLY and not should_emit_event(): + return False + return True + + class _GenAiJsonEncoder(json.JSONEncoder): def default(self, o: Any) -> Any: if isinstance(o, bytes): diff --git a/util/opentelemetry-util-genai/tests/test_events_options.py b/util/opentelemetry-util-genai/tests/test_events_options.py index 78476de8800..1095d39d248 100644 --- a/util/opentelemetry-util-genai/tests/test_events_options.py +++ b/util/opentelemetry-util-genai/tests/test_events_options.py @@ -25,6 +25,7 @@ OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT, ) from opentelemetry.util.genai.utils import ( + should_capture_content_on_spans_in_experimental_mode, should_emit_event, ) @@ -206,3 +207,45 @@ def test_should_emit_event_user_setting_overrides_default_for_no_content( ): # pylint: disable=no-self-use # User explicitly setting emit_event="true" should override the default (False for NO_CONTENT) assert should_emit_event() is True + + +class TestShouldCaptureContent(unittest.TestCase): + @patch_env_vars( + stability_mode="default", + content_capturing="SPAN_AND_EVENT", + emit_event="true", + ) + def test_should_capture_content_on_spans_in_experimental_mode_false_when_not_experimental( + self, + ): # pylint: disable=no-self-use + assert should_capture_content_on_spans_in_experimental_mode() is False + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="NO_CONTENT", + emit_event="true", + ) + def test_should_capture_content_on_spans_in_experimental_mode_false_when_no_content( + self, + ): # pylint: disable=no-self-use + assert should_capture_content_on_spans_in_experimental_mode() is False + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="EVENT_ONLY", + emit_event="false", + ) + def test_should_capture_content_on_spans_in_experimental_mode_false_when_event_only_but_event_disabled( + self, + ): # pylint: disable=no-self-use + assert should_capture_content_on_spans_in_experimental_mode() is False + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="SPAN_ONLY", + emit_event="", + ) + def test_should_capture_content_on_spans_in_experimental_mode_true_for_span_only( + self, + ): # pylint: disable=no-self-use + assert should_capture_content_on_spans_in_experimental_mode() is True diff --git a/uv.lock b/uv.lock index 6b2e6e21edb..d2aae93537f 100644 --- a/uv.lock +++ b/uv.lock @@ -2858,7 +2858,7 @@ instruments = [ [package.metadata] requires-dist = [ - { name = "anthropic", marker = "extra == 'instruments'", specifier = ">=0.16.0" }, + { name = "anthropic", marker = "extra == 'instruments'", specifier = ">=0.51.0" }, { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, From 4df92e287ab5feee0c8ec6017e9d3b4d1bb38355 Mon Sep 17 00:00:00 2001 From: Teja Date: Tue, 10 Mar 2026 00:06:34 -0400 Subject: [PATCH 07/78] Add response wrappers for OpenAI Responses API streams. (#4280) * Add response wrappers for OpenAI Responses API streams. * Enhance docstrings for ResponseStreamWrapper and ResponseStreamManagerWrapper to include references to the OpenAI SDK source. This improves clarity on the functionality and origin of the wrappers. * Add wrappers for OpenAI Responses API streams and response stream managers in CHANGELOG.md * Refactor response handling in OpenAI response wrappers to improve event processing and error handling. Introduced conditional imports for response events and error types, ensuring compatibility with missing modules. Updated event processing logic to utilize a consolidated response events tuple. * Refactor OpenAI response wrappers to enhance error handling and event processing. Introduced context managers for safe instrumentation, improved import handling for response events, and streamlined response attribute extraction logic. * Add unit tests for ResponseStreamManagerWrapper to validate error handling and stream finalization behavior. * Remove unnecessary blank line in test_response_wrappers.py to improve code cleanliness. * Refactor event handling in ResponseStreamWrapper to simplify type checks for response events. Removed unnecessary conditional checks for event types, enhancing code clarity and maintainability. * Enhance ResponseStreamWrapper and ResponseStreamManagerWrapper with improved error handling and context management. Introduced ExitStack for better resource management and added NotImplementedError for unimplemented parse methods. Updated TODO comments for future refactoring with wrapt.ObjectProxy. --- .../CHANGELOG.md | 2 + .../openai_v2/response_wrappers.py | 305 ++++++++++++++++++ .../tests/test_response_wrappers.py | 106 ++++++ 3 files changed, 413 insertions(+) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 9132163d9b1..051ecac9a9c 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `OTEL_SEMCONV_STABILITY_OPT_IN` to `gen_ai_latest_experimental` to enable. Add dependency on `opentelemetry-util-genai` pypi package. ([#3715](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3715)) +- Add wrappers for OpenAI Responses API streams and response stream managers + ([#4280](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4280)) ## Version 2.3b0 (2025-12-24) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py new file mode 100644 index 00000000000..360bde464c5 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py @@ -0,0 +1,305 @@ +"""Wrappers for OpenAI Responses API streams and stream managers.""" + +from __future__ import annotations + +import logging +from contextlib import ExitStack, contextmanager +from types import TracebackType +from typing import TYPE_CHECKING, Callable, Generator, Generic, TypeVar + +from opentelemetry.util.genai.handler import TelemetryHandler +from opentelemetry.util.genai.types import Error, LLMInvocation + +# OpenAI Responses internals are version-gated (added in openai>=1.66.0), so +# pylint may not resolve them in all lint environments even though we guard +# runtime usage with ImportError fallbacks below. +try: + from openai.lib.streaming.responses._events import ( # pylint: disable=no-name-in-module + ResponseCompletedEvent, + ) + from openai.types.responses import ( # pylint: disable=no-name-in-module + ResponseCreatedEvent, + ResponseErrorEvent, + ResponseFailedEvent, + ResponseIncompleteEvent, + ResponseInProgressEvent, + ) + + _RESPONSE_EVENTS_WITH_RESPONSE = ( + ResponseCreatedEvent, + ResponseInProgressEvent, + ResponseFailedEvent, + ResponseIncompleteEvent, + ResponseCompletedEvent, + ) +except ImportError: + ResponseCompletedEvent = None + ResponseCreatedEvent = None + ResponseErrorEvent = None + ResponseFailedEvent = None + ResponseIncompleteEvent = None + ResponseInProgressEvent = None + _RESPONSE_EVENTS_WITH_RESPONSE = () + +try: + from opentelemetry.instrumentation.openai_v2.response_extractors import ( # pylint: disable=no-name-in-module + _set_invocation_response_attributes, + ) +except ImportError: + _set_invocation_response_attributes = None + +if TYPE_CHECKING: + from openai.lib.streaming.responses._events import ( # pylint: disable=no-name-in-module + ResponseStreamEvent, + ) + from openai.lib.streaming.responses._responses import ( + ResponseStream, + ResponseStreamManager, + ) # pylint: disable=no-name-in-module + from openai.types.responses import ( # pylint: disable=no-name-in-module + ParsedResponse, + Response, + ) + +_logger = logging.getLogger(__name__) +TextFormatT = TypeVar("TextFormatT") +ResponseT = TypeVar("ResponseT") + + +def _set_response_attributes( + invocation: "LLMInvocation", + result: "ParsedResponse[TextFormatT] | Response | None", + capture_content: bool, +) -> None: + if _set_invocation_response_attributes is None: + return + _set_invocation_response_attributes(invocation, result, capture_content) + + +class _ResponseProxy(Generic[ResponseT]): + def __init__(self, response: ResponseT, finalize: Callable[[], None]): + self._response = response + self._finalize = finalize + + def close(self) -> None: + try: + self._response.close() + finally: + self._finalize() + + def __getattr__(self, name: str): + return getattr(self._response, name) + + +class ResponseStreamWrapper(Generic[TextFormatT]): + """Wrapper for OpenAI Responses API stream objects. + + Wraps ResponseStream from the OpenAI SDK: + https://github.com/openai/openai-python/blob/656e3cab4a18262a49b961d41293367e45ee71b9/src/openai/_streaming.py#L55 + """ + + def __init__( + self, + stream: "ResponseStream[TextFormatT]", + handler: TelemetryHandler, + invocation: "LLMInvocation", + capture_content: bool, + ): + self.stream = stream + self.handler = handler + self.invocation = invocation + self._capture_content = capture_content + self._finalized = False + + def __enter__(self) -> "ResponseStreamWrapper": + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + try: + if exc_type is not None: + self._fail( + str(exc_val), type(exc_val) if exc_val else Exception + ) + finally: + self.close() + return False + + def close(self) -> None: + try: + self.stream.close() + finally: + self._stop(None) + + def __iter__(self) -> "ResponseStreamWrapper": + return self + + def __next__(self) -> "ResponseStreamEvent[TextFormatT]": + try: + event = next(self.stream) + except StopIteration: + self._stop(None) + raise + except Exception as error: + self._fail(str(error), type(error)) + raise + with self._safe_instrumentation("event processing"): + self.process_event(event) + return event + + def get_final_response(self) -> "ParsedResponse[TextFormatT]": + self.until_done() + return self.stream.get_final_response() + + def until_done(self) -> "ResponseStreamWrapper": + for _ in self: + pass + return self + + def parse(self) -> "ResponseStreamWrapper": + raise NotImplementedError( + "ResponseStreamWrapper.parse() is not implemented" + ) + + # TODO: Replace __getattr__ passthrough with wrapt.ObjectProxy in a future + # cleanup once wrapt 2 typing support is available (wrapt PR #3903). + def __getattr__(self, name: str): + return getattr(self.stream, name) + + @property + def response(self): + response = self.stream.response + if response is None: + return None + return _ResponseProxy(response, lambda: self._stop(None)) + + def _stop( + self, result: "ParsedResponse[TextFormatT] | Response | None" + ) -> None: + if self._finalized: + return + with self._safe_instrumentation("response attribute extraction"): + _set_response_attributes( + self.invocation, result, self._capture_content + ) + with self._safe_instrumentation("stop_llm"): + self.handler.stop_llm(self.invocation) + self._finalized = True + + def _fail(self, message: str, error_type: type[BaseException]) -> None: + if self._finalized: + return + with self._safe_instrumentation("fail_llm"): + self.handler.fail_llm( + self.invocation, Error(message=message, type=error_type) + ) + self._finalized = True + + @staticmethod + @contextmanager + def _safe_instrumentation(context: str) -> Generator[None, None, None]: + try: + yield + except Exception: # pylint: disable=broad-exception-caught + _logger.debug( + "OpenAI responses instrumentation error during %s", + context, + exc_info=True, + stacklevel=2, + ) + + def process_event(self, event: "ResponseStreamEvent[TextFormatT]") -> None: + event_type = event.type + response: "ParsedResponse[TextFormatT] | Response | None" = None + + if isinstance(event, _RESPONSE_EVENTS_WITH_RESPONSE): + response = event.response + + if response and not self.invocation.request_model: + model = response.model + if model: + self.invocation.request_model = model + + if isinstance(event, ResponseCompletedEvent): + self._stop(response) + return + + if isinstance(event, (ResponseFailedEvent, ResponseIncompleteEvent)): + with self._safe_instrumentation("response attribute extraction"): + _set_response_attributes( + self.invocation, response, self._capture_content + ) + self._fail(event_type, RuntimeError) + return + + if isinstance(event, ResponseErrorEvent): + error_type = event.code or "response.error" + message = event.message or error_type + self._fail(message, RuntimeError) + + +class ResponseStreamManagerWrapper(Generic[TextFormatT]): + """Wrapper for OpenAI Responses API stream managers. + + Wraps ResponseStreamManager from the OpenAI SDK: + https://github.com/openai/openai-python/blob/656e3cab4a18262a49b961d41293367e45ee71b9/src/openai/lib/streaming/responses/_responses.py#L95 + """ + + def __init__( + self, + manager: "ResponseStreamManager[TextFormatT]", + handler: TelemetryHandler, + invocation: "LLMInvocation", + capture_content: bool, + ): + self._manager = manager + self._handler = handler + self._invocation = invocation + self._capture_content = capture_content + self._stream_wrapper: ResponseStreamWrapper[TextFormatT] | None = None + + def __enter__(self) -> ResponseStreamWrapper[TextFormatT]: + stream = self._manager.__enter__() + self._stream_wrapper = ResponseStreamWrapper( + stream, + self._handler, + self._invocation, + self._capture_content, + ) + return self._stream_wrapper + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + suppressed = False + stream_wrapper = self._stream_wrapper + self._stream_wrapper = None + with ExitStack() as cleanup: + if stream_wrapper is not None: + + def finalize_stream_wrapper() -> None: + if suppressed: + stream_wrapper.__exit__(None, None, None) + else: + stream_wrapper.__exit__(exc_type, exc_val, exc_tb) + + cleanup.callback(finalize_stream_wrapper) + suppressed = self._manager.__exit__(exc_type, exc_val, exc_tb) + return suppressed + + def parse(self) -> "ResponseStreamManagerWrapper[TextFormatT]": + raise NotImplementedError( + "ResponseStreamManagerWrapper.parse() is not implemented" + ) + + # TODO: Replace __getattr__ passthrough with wrapt.ObjectProxy in a future + # cleanup once wrapt 2 typing support is available (wrapt PR #3903). + def __getattr__(self, name: str): + return getattr(self._manager, name) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py new file mode 100644 index 00000000000..803a55e4a8a --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py @@ -0,0 +1,106 @@ +# 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 types import SimpleNamespace + +import pytest + +from opentelemetry.instrumentation.openai_v2.response_wrappers import ( + ResponseStreamManagerWrapper, +) + + +class _FakeManager: + def __init__(self, stream, suppressed=False, exit_error=None): + self._stream = stream + self._suppressed = suppressed + self._exit_error = exit_error + self.exit_args = None + + def __enter__(self): + return self._stream + + def __exit__(self, exc_type, exc_val, exc_tb): + self.exit_args = (exc_type, exc_val, exc_tb) + if self._exit_error is not None: + raise self._exit_error + return self._suppressed + + +def _make_wrapper(manager): + handler = SimpleNamespace() + invocation = SimpleNamespace(request_model=None) + return ResponseStreamManagerWrapper( + manager=manager, + handler=handler, + invocation=invocation, + capture_content=False, + ) + + +class _FakeStreamWrapper: + def __init__(self): + self.exit_args = None + + def __exit__(self, exc_type, exc_val, exc_tb): + self.exit_args = (exc_type, exc_val, exc_tb) + return False + + +def test_manager_exit_forwards_exception_to_stream_wrapper(): + manager = _FakeManager(stream=SimpleNamespace(), suppressed=False) + wrapper = _make_wrapper(manager) + stream_wrapper = _FakeStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = ValueError("boom") + result = wrapper.__exit__(ValueError, error, None) + + assert result is False + assert manager.exit_args == (ValueError, error, None) + assert stream_wrapper.exit_args == (ValueError, error, None) + assert wrapper._stream_wrapper is None + + +def test_manager_exit_uses_none_exception_when_manager_suppresses(): + manager = _FakeManager(stream=SimpleNamespace(), suppressed=True) + wrapper = _make_wrapper(manager) + stream_wrapper = _FakeStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = RuntimeError("ignored") + result = wrapper.__exit__(RuntimeError, error, None) + + assert result is True + assert manager.exit_args == (RuntimeError, error, None) + assert stream_wrapper.exit_args == (None, None, None) + assert wrapper._stream_wrapper is None + + +def test_manager_exit_still_finalizes_stream_wrapper_when_manager_raises(): + manager_error = RuntimeError("manager failure") + manager = _FakeManager( + stream=SimpleNamespace(), suppressed=False, exit_error=manager_error + ) + wrapper = _make_wrapper(manager) + stream_wrapper = _FakeStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = ValueError("outer") + with pytest.raises(RuntimeError, match="manager failure"): + wrapper.__exit__(ValueError, error, None) + + assert manager.exit_args == (ValueError, error, None) + assert stream_wrapper.exit_args == (ValueError, error, None) + assert wrapper._stream_wrapper is None From 82e72435d07dba350634811c0028d1242bc9d9b0 Mon Sep 17 00:00:00 2001 From: Manuel Lang Date: Tue, 10 Mar 2026 11:43:05 +0100 Subject: [PATCH 08/78] opentelemetry-instrumentation-confluent-kafka: Loosen confluent-kafka upper bound to <3.0.0 (#4289) * opentelemetry-instrumentation-confluent-kafka: Add support for confluent-kafka 2.13.2 * chore: Losen confluent-kafka upper bound to <3.0.0 --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 5 ++ docs-requirements.txt | 2 +- instrumentation/README.md | 2 +- .../pyproject.toml | 9 +-- .../confluent_kafka/package.py | 2 +- .../test-requirements.txt | 2 +- .../instrumentation/bootstrap_gen.py | 2 +- uv.lock | 64 +++++++++---------- 8 files changed, 42 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e68eb2cd82..acc5bee1b02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- `opentelemetry-instrumentation-confluent-kafka`: Loosen confluent-kafka upper bound to <3.0.0 + ([#4289](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4289)) + ### Fixed - Fix intermittent `Core Contrib Test` CI failures caused by GitHub git CDN SHA propagation lag by installing core packages from the already-checked-out local copy instead of a second git clone diff --git a/docs-requirements.txt b/docs-requirements.txt index 4914e9f780f..99c7327c178 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -27,7 +27,7 @@ botocore~=1.0 boto3~=1.0 cassandra-driver~=3.25 celery>=4.0 -confluent-kafka>= 1.8.2,<= 2.13.0 +confluent-kafka>= 1.8.2,< 3.0.0 elasticsearch>=6.0,<9.0 flask~=2.0 falcon~=2.0 diff --git a/instrumentation/README.md b/instrumentation/README.md index 27008c0015e..d8b4b7216f1 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -17,7 +17,7 @@ | [opentelemetry-instrumentation-cassandra](./opentelemetry-instrumentation-cassandra) | cassandra-driver ~= 3.25,scylla-driver ~= 3.25 | No | development | [opentelemetry-instrumentation-celery](./opentelemetry-instrumentation-celery) | celery >= 4.0, < 6.0 | No | development | [opentelemetry-instrumentation-click](./opentelemetry-instrumentation-click) | click >= 8.1.3, < 9.0.0 | No | development -| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, <= 2.13.0 | No | development +| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, < 3.0.0 | No | development | [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | development | [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 2.0 | Yes | development | [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | development diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index d28eb98593b..fb1f4ac8971 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -32,9 +32,7 @@ dependencies = [ ] [project.optional-dependencies] -instruments = [ - "confluent-kafka >= 1.8.2, <= 2.13.0", -] +instruments = ["confluent-kafka >= 1.8.2, < 3.0.0"] [project.entry-points.opentelemetry_instrumentor] confluent_kafka = "opentelemetry.instrumentation.confluent_kafka:ConfluentKafkaInstrumentor" @@ -47,10 +45,7 @@ Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" path = "src/opentelemetry/instrumentation/confluent_kafka/version.py" [tool.hatch.build.targets.sdist] -include = [ - "/src", - "/tests", -] +include = ["/src", "/tests"] [tool.hatch.build.targets.wheel] packages = ["src/opentelemetry"] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py index e7aa44893a6..23aca3b92d3 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py @@ -13,4 +13,4 @@ # limitations under the License. -_instruments = ("confluent-kafka >= 1.8.2, <= 2.13.0",) +_instruments = ("confluent-kafka >= 1.8.2, < 3.0.0",) diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index 3e9b88bbdb9..cf5791b3277 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -1,5 +1,5 @@ asgiref==3.8.1 -confluent-kafka==2.13.0 +confluent-kafka==2.13.2 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index ee73007fca6..3aac3453fe2 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -85,7 +85,7 @@ "instrumentation": "opentelemetry-instrumentation-click==0.62b0.dev", }, { - "library": "confluent-kafka >= 1.8.2, <= 2.13.0", + "library": "confluent-kafka >= 1.8.2, < 3.0.0", "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.62b0.dev", }, { diff --git a/uv.lock b/uv.lock index d2aae93537f..826755f784d 100644 --- a/uv.lock +++ b/uv.lock @@ -907,39 +907,35 @@ wheels = [ [[package]] name = "confluent-kafka" -version = "2.13.0" -source = { registry = "https://pypi.org/simple/" } -sdist = { url = "https://files.pythonhosted.org/packages/b4/d0/1f5055331fa660225de6829b143e6f083913f0a96481134a91390bad62c1/confluent_kafka-2.13.0.tar.gz", hash = "sha256:eff7a4391a9e6d4a33f0c05d0935b200a7463834f1f5d6e6253be318f910babd", size = 273621, upload-time = "2026-01-05T10:25:08.078Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/75/b3ac0e7fc74a577eb58872f07faef3d1d50a1e1ac7d105b167d330105bc5/confluent_kafka-2.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:264f86956d3bbd26bc14fd2d4060908a0c53d26b14ff33d21fa83369f55d8d3b", size = 3626152, upload-time = "2026-01-05T10:23:21.034Z" }, - { url = "https://files.pythonhosted.org/packages/17/7c/897913554793d43fcf69e0bfa1ba2b647e007f45fa43b190645e5b5f6518/confluent_kafka-2.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4af5f129acce30110c7a1c9c05c54821c1283850e38c67715bed7c3c8df322c6", size = 3186880, upload-time = "2026-01-05T10:23:24.382Z" }, - { url = "https://files.pythonhosted.org/packages/27/7c/c956373d15a57290b9d00c5e2c1a5fb65b8d4f77fa64535ad7370d9ed750/confluent_kafka-2.13.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:9b975664e821d975c85ec9bba806b7c62eb9b23cf2ad3b41813862ee24caf00e", size = 3715940, upload-time = "2026-01-05T10:23:29.266Z" }, - { url = "https://files.pythonhosted.org/packages/10/92/66179579a1bbc91f2e700841ea698a99c8108580e46c2cd5b1812c707c38/confluent_kafka-2.13.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:fc633deedd3eba5c266bf12959d8c4173806d252db45d2c78d3bd9a874dc7ccf", size = 3973310, upload-time = "2026-01-05T10:23:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/9c/e6/66d3bd816d996058f9f46b46953e79b3ea2662f3538d0682a3f52f651393/confluent_kafka-2.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:2c0b19a83f519de8f2cb170bc7879b1d92ac342a75798722fbfe29965f21d5ad", size = 4093322, upload-time = "2026-01-05T10:23:34.235Z" }, - { url = "https://files.pythonhosted.org/packages/94/57/a90b9042a06bfbb8cc1e50142b8bcea29fde57a528dc10b188835e7c5c53/confluent_kafka-2.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:af19d6a2ab49f02cf699bc1dfb6f4bdcc3588e077c7b5319d73335b81fef93fd", size = 3625719, upload-time = "2026-01-05T10:23:36.469Z" }, - { url = "https://files.pythonhosted.org/packages/5a/ee/d0839c64de344de247d80b6f69a2d7f5d781bb55bdd1e98793549780a34d/confluent_kafka-2.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a406800c29e568e61ab687540391ac8eab210b79d24d7eb41b75b6117882e269", size = 3186456, upload-time = "2026-01-05T10:23:38.742Z" }, - { url = "https://files.pythonhosted.org/packages/2b/e7/6224ab1c5dad5d70717f3e018f1d676be1d54ce3ea08b04b1d19e94484dc/confluent_kafka-2.13.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9bc38055f5a26bec15ca81b0465f90cb2663a31c19948d6421dc02090b4cbd4a", size = 3715598, upload-time = "2026-01-05T10:23:41.018Z" }, - { url = "https://files.pythonhosted.org/packages/64/88/a7a7ee4fdcca5340809482e6565cd3270fe82afd029a14cf921b51eef152/confluent_kafka-2.13.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:7080a20f64293b1f81747748e6bda0d1e9a9d5d5f94cd1b0c625cfdf819f491f", size = 3972822, upload-time = "2026-01-05T10:23:44.029Z" }, - { url = "https://files.pythonhosted.org/packages/5f/46/2879be2a40b9b44a527a16c117c6a5f380fdd10d6735b43bce6fab6102d7/confluent_kafka-2.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:39fdfd4fa6371ebabf9e7be858ae68d4fa9a9fd72fd5fc3d739fdaa99997fd9a", size = 4093320, upload-time = "2026-01-05T10:23:46.347Z" }, - { url = "https://files.pythonhosted.org/packages/e9/cc/6bf9e5b3ee4bfdb39d3fcc7efabc9f577aa51e9e20139adc8d10e61593a5/confluent_kafka-2.13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a69263f22a8c53c7d55067e7795ed49d22c374b9473df91982816a0448e6d242", size = 3631367, upload-time = "2026-01-05T10:23:48.076Z" }, - { url = "https://files.pythonhosted.org/packages/10/3d/c299df69885be6fdfc8b105b8106b2b4c73c745fa608cf579eb7e14a3da9/confluent_kafka-2.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0945c7f529e66a18aa19135aa18bfdc239ca6c0f6df6ca9b05a793d9b76c1c4b", size = 3191073, upload-time = "2026-01-05T10:23:49.967Z" }, - { url = "https://files.pythonhosted.org/packages/82/2e/854aedcd9c9042491c1fcafaadc03a3b0e357ddc23044781d02920b46ea2/confluent_kafka-2.13.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:321037a64c02acb13b5bde193b461c0514dca236a9f5236c847a3240313c297f", size = 3720530, upload-time = "2026-01-05T10:23:51.957Z" }, - { url = "https://files.pythonhosted.org/packages/1d/4a/210f0e1f8e77956ed1296c8b9bac2093413c1669ea0e923f590f2827aa1a/confluent_kafka-2.13.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d7a71ca8fd42d3eefa22eb202e7fc8a419e0fd4e3b59862918c21f4d1074f0c5", size = 3977296, upload-time = "2026-01-05T10:23:56.743Z" }, - { url = "https://files.pythonhosted.org/packages/b0/bc/d51f48200bb7bec521289c0b70691ea73f91aa76529b1bff807bcbf89b12/confluent_kafka-2.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:37dddb1b92829b8862bc4fbce07789a79b73aa31eca413f3db187721a09975ff", size = 4093802, upload-time = "2026-01-05T10:23:58.703Z" }, - { url = "https://files.pythonhosted.org/packages/77/bd/c2ab440b4c4847a37b21e9623bbeaf17982ca45595ad62b8435a26d680f7/confluent_kafka-2.13.0-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:0af90b3c566786017a01693da0ec4a876ca14cf37bc6164872652a6cf2702453", size = 3195849, upload-time = "2026-01-05T10:24:00.854Z" }, - { url = "https://files.pythonhosted.org/packages/6a/40/a25a5895cf522bada81fc7ba6c0ad29219843206ede4e8d2138b7b095652/confluent_kafka-2.13.0-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:f25d05604dd92e9de72707582dded53aeb4737ef2e2c097a3ca08650200fc446", size = 3634806, upload-time = "2026-01-05T10:24:05.496Z" }, - { url = "https://files.pythonhosted.org/packages/fd/46/db30d27184ac8fb673ca469d576ef582def0b613a69456631734f7a5e267/confluent_kafka-2.13.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:74ddf5ec7fa6058221a619c850f44bdbe8d969d7ed6efe8abdc857d2e233df20", size = 3720848, upload-time = "2026-01-05T10:24:07.831Z" }, - { url = "https://files.pythonhosted.org/packages/fc/f8/5b940a080ab71fc3c585839eae0c26341a749a7ebc001fca0276aff9df40/confluent_kafka-2.13.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:f8d1d00397f3f32a1bcf4604d4164bf75838bd009e1e28282a7ae25e16814ea4", size = 3977677, upload-time = "2026-01-05T10:24:09.988Z" }, - { url = "https://files.pythonhosted.org/packages/e1/cf/f9f979c08cfe1b8fd9203b329fc5c8c410e948f01272434bc1ce0c6334a5/confluent_kafka-2.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9d1fd035e2c47c4db5fe9b0f59a28fe2f2f1012887290dd0ea7d46741f686e99", size = 4153481, upload-time = "2026-01-05T10:24:12.167Z" }, - { url = "https://files.pythonhosted.org/packages/06/3f/c2120c002f85c5401d8ea29558acf041ad968b33cfca83916a7c0a740d53/confluent_kafka-2.13.0-cp314-cp314-macosx_13_0_arm64.whl", hash = "sha256:d448537147a33dd8c17656732989ddfe1d4a25a40bcb5f59bc63dc0a5041dd83", size = 3195696, upload-time = "2026-01-05T10:24:14.422Z" }, - { url = "https://files.pythonhosted.org/packages/35/b9/da4ef8fca4cbc76b6040a97a92085c09c0f23c42424989a2d68cec42c8d6/confluent_kafka-2.13.0-cp314-cp314-macosx_13_0_x86_64.whl", hash = "sha256:1325585f9fc283c32c30df4226178dc89cf43d00f5c240e1f77ddedc94573690", size = 3634632, upload-time = "2026-01-05T10:24:16.575Z" }, - { url = "https://files.pythonhosted.org/packages/09/ed/c7d5cc3c57aec126ffb12ffa5f4584acd264446a4117db3ad2dd69e47afe/confluent_kafka-2.13.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:266bbea18ce99f6e77ce0e9a118f353447c8705792ef5745eabcc5c6db08794a", size = 3720650, upload-time = "2026-01-05T10:24:18.657Z" }, - { url = "https://files.pythonhosted.org/packages/c3/2b/0a93b63a46b2ceaac3de92d494e32aab21bec398b40ac89108bbaa6894c3/confluent_kafka-2.13.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:7a373a1a3dd8e02dd218946583e951791480921fd777faeaf601c2834e2a6c0d", size = 3977364, upload-time = "2026-01-05T10:24:23.677Z" }, - { url = "https://files.pythonhosted.org/packages/46/00/80ea6872421c4e30e033e035e5bdcf44c054993d5721623841c59b5f04c1/confluent_kafka-2.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:da956b2141d9f425dbfc3cf1c244ef6d0633b83fc5ceada6f496099258e63a68", size = 4271874, upload-time = "2026-01-05T10:24:26.265Z" }, - { url = "https://files.pythonhosted.org/packages/fc/1a/e6fe016bea63343010f485a1ecebfdc00d9b6e95ef6fe52a1d7793c0339c/confluent_kafka-2.13.0-cp314-cp314t-macosx_13_0_arm64.whl", hash = "sha256:fa354e9fb95e26545decd429477072ea3a98a2e7acac11d09156772e06f14680", size = 3194480, upload-time = "2026-01-05T10:24:28.515Z" }, - { url = "https://files.pythonhosted.org/packages/fb/54/c9668f214f2e736e51e2874053fe1ebcb8784425fefcfd6fd0d384dc5dcf/confluent_kafka-2.13.0-cp314-cp314t-macosx_13_0_x86_64.whl", hash = "sha256:e256dc3a993bf5fde0fa4a1b6a5b72e3521cedbc9dc4d7a65f159afa4b72e5b4", size = 3632866, upload-time = "2026-01-05T10:24:30.689Z" }, - { url = "https://files.pythonhosted.org/packages/13/f5/83e989962077003d91ba249158c7a1e21696604c301b3680fcbb427005d0/confluent_kafka-2.13.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:eb7988038b7f13ea490af93b9165ed40a3f385fb91e99ce8dacee8890e36e48a", size = 3718956, upload-time = "2026-01-05T10:24:33.035Z" }, - { url = "https://files.pythonhosted.org/packages/b8/84/1aaa5cfe1695f02d11e02ef39f180567780348b1f3e1161575f002a207fe/confluent_kafka-2.13.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:cfd8f011b0b0a109f8747312dba6cee45b39fb53fc7d53f28813bce84a91228d", size = 3976235, upload-time = "2026-01-05T10:24:35.122Z" }, +version = "2.13.2" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/7a/38/f5855cae6d328fa66e689d068709f91cbbd4d72e7e03959998bd43ac6b26/confluent_kafka-2.13.2.tar.gz", hash = "sha256:619d10d1d77c9821ba913b3e42a33ade7f889f3573c7f3c17b57c3056e3310f5", size = 276068, upload-time = "2026-03-02T12:53:31.457Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/7c/bd4c2f49ecba57d3338b2f8b466530696eb65565480c18347539cc3104da/confluent_kafka-2.13.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4ee145e9b05fa56b3da104c3fda0cd63c22dd609ee6d8efea6e87a96ef4ad74", size = 3630069, upload-time = "2026-03-02T12:52:33.637Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f4/b6178a474f725c0aa389ad048c7eba91ea12eb0d392dab26f39d2cf95d60/confluent_kafka-2.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:478f11030a8ee7fafc816b4067f586222adbdc47d710f7e54eceb22a56320359", size = 3190436, upload-time = "2026-03-02T12:52:36.852Z" }, + { url = "https://files.pythonhosted.org/packages/48/6b/08c1efee551e513aa2e61d5583fe7d7bdf870372dfaf6ecf75ec96bdd7ff/confluent_kafka-2.13.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:92bf91c718911d7542aa6e1f60822fe9325b1a5173c5dd64b87c717246788ba2", size = 3719853, upload-time = "2026-03-02T12:52:38.549Z" }, + { url = "https://files.pythonhosted.org/packages/ba/67/98dfe8e699bfa6da0dbf9e03bd23c179ff0c9f27b88448a1d613de9a0d71/confluent_kafka-2.13.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8b4dd67cb7a973382e02e8ba26e33caf0c70910cf74ef077ca2ad99387fc154a", size = 3976926, upload-time = "2026-03-02T12:52:39.915Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/534803e8e1fd8246f66c651131c2c02b30c0c8018b3d6c04e9dd80abd792/confluent_kafka-2.13.2-cp310-cp310-win_amd64.whl", hash = "sha256:e36f978d425deda2e57e832b3b9ac733c3668f2dae955b8953df8ae986e3cf5b", size = 4097308, upload-time = "2026-03-02T12:52:41.225Z" }, + { url = "https://files.pythonhosted.org/packages/71/a7/7dfee75b246f5e5f0832a27e365cd9e8050591c5f4301714672bea2375ce/confluent_kafka-2.13.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e85dc2aaf08dcac610d20b24d252a24891440cf33c09396c957781b8a1f24015", size = 3629660, upload-time = "2026-03-02T12:52:42.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/77/bc6bca93f455e91b41b196bb208b9cbfc517442a65abae2391f1af64cd2f/confluent_kafka-2.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eb1b218beeaae36b3fc94927e30df5f6d662858e766eada2369b290df0b1bff0", size = 3190013, upload-time = "2026-03-02T12:52:44.193Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ce/2ee04c1b2707b6dd7177eab40fced00b474671d2303e5096d96f3bf7e231/confluent_kafka-2.13.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69b4286296504b89c0c3cd1e531d12053c633e56d2c5b477ff9000524fe24eb5", size = 3719524, upload-time = "2026-03-02T12:52:45.488Z" }, + { url = "https://files.pythonhosted.org/packages/7c/93/5c40e2f7eae52774db6b14060254d001ae8c4ef8d4385bf2f13294dd929f/confluent_kafka-2.13.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e47be4267d3feda5bf1c066f140f61e61ea28bd6ecdb60c2a52ec1a91b8903e7", size = 3976453, upload-time = "2026-03-02T12:52:47.787Z" }, + { url = "https://files.pythonhosted.org/packages/46/85/a3d25b67470abbd4835fca714a419465323ba79dceefcdda65dfa4415c80/confluent_kafka-2.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:84dd6e7f456910aa4d4763d86efa0dded7167fdf1251b51d808dec0f124f5e13", size = 4097308, upload-time = "2026-03-02T12:52:49.083Z" }, + { url = "https://files.pythonhosted.org/packages/d9/d3/a845c6993a728b8b6bdce9b500d15c3ec3663cd95d2bbf9c1b8cfd519b17/confluent_kafka-2.13.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e259c0d2b9a7e16211b45404f62869502246ac3d03e35a1f80720fd09d262457", size = 3635348, upload-time = "2026-03-02T12:52:50.927Z" }, + { url = "https://files.pythonhosted.org/packages/ab/22/1cb998f7b3ee613d5b29f4b98e4a7539776eb0819b89d7c3cdd19a685692/confluent_kafka-2.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:77ea4ceccdbb67498787b7c02cc329c32417bb730e9383f46c74eb9c5851763c", size = 3194667, upload-time = "2026-03-02T12:52:53.468Z" }, + { url = "https://files.pythonhosted.org/packages/11/38/8a1b12321068e8ae126e62600a55d7a1872f969e1de5ec7f602e0dba8394/confluent_kafka-2.13.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:a64a8967734f865f54b766553d63a40f17081cd3d2c6cfe6d3217aa7494d88fb", size = 3724453, upload-time = "2026-03-02T12:52:55.187Z" }, + { url = "https://files.pythonhosted.org/packages/5c/06/3effa66c59a69e17cc48c69ae2533699f4321fac1b46741f2e4b1aefb1e7/confluent_kafka-2.13.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e4cb7d112463ec15a01a3f0e0d20392cda6e46156a6439fcaaad2267696f5cde", size = 3980919, upload-time = "2026-03-02T12:52:56.852Z" }, + { url = "https://files.pythonhosted.org/packages/98/22/f76a8b85fad652b4d5c0a0259c8f7bb66393d2d9f277631c754c9ebe5092/confluent_kafka-2.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:44496777ff0104421b8f4bb269728e8a5e772c09f34ae813bc47110e0172ebe0", size = 4097817, upload-time = "2026-03-02T12:52:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/ae9a7f21ba49e55b1be18362cefd7648e4aceb588e254f9ee5edb97fcf44/confluent_kafka-2.13.2-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:02702808dd3cfd91f117fbf17181da2a95392967e9f946b1cbdc5589b36e39d1", size = 3199459, upload-time = "2026-03-02T12:53:00.614Z" }, + { url = "https://files.pythonhosted.org/packages/12/94/ccd92f9a3bb685b265bc83ede699651aa526502e4988e906e710d3f24cd3/confluent_kafka-2.13.2-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:7dc3a2da92638c077bbabb07058f1938078b42a89f0bbfdcb852d4289c2de27e", size = 3638743, upload-time = "2026-03-02T12:53:01.951Z" }, + { url = "https://files.pythonhosted.org/packages/ba/66/048925a546a0f8e9134a89441aa4ae663892839004668d1039d5f9dd8d45/confluent_kafka-2.13.2-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:f3e6d010ad38447a48e0f9fab81edd4d2fd0b5f5a79ab475c30347689e35c6e6", size = 3724788, upload-time = "2026-03-02T12:53:03.775Z" }, + { url = "https://files.pythonhosted.org/packages/ca/a6/53faa22d52d8fc6f58424d4b6c2c32855198fcb776ea8b4404ee50b58c72/confluent_kafka-2.13.2-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:9161865d8246eb77d1c30233a315bdad96145af783981877664532fa212f56be", size = 3981324, upload-time = "2026-03-02T12:53:05.339Z" }, + { url = "https://files.pythonhosted.org/packages/02/a8/1578956d3721645b24c22b0e9ceeab794fffc197a32074a7572bfbc07ca7/confluent_kafka-2.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:931233798306b859f4870ec58e3951a2bd32d14ef29f944f56892851b0aafab0", size = 4157492, upload-time = "2026-03-02T12:53:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/6a/4c/46f09fcc1dedebb0a0884b072ddde74be8a8bcfb5e3fbc912bd2c8255e6f/confluent_kafka-2.13.2-cp314-cp314-macosx_13_0_arm64.whl", hash = "sha256:9cb0d6820107deca1823d68b96831bd982d0a11c4e6bcf0a12e8040192c48a8f", size = 3199305, upload-time = "2026-03-02T12:53:08.351Z" }, + { url = "https://files.pythonhosted.org/packages/37/3c/56d052bdedb7d4bb56bf993dc017df4434e2eb5e73745f22d0beb3c32999/confluent_kafka-2.13.2-cp314-cp314-macosx_13_0_x86_64.whl", hash = "sha256:b31d94bca493d84927927d1bdd59e1b6d3d921019a657f99f0c8cc5da8c85311", size = 3638586, upload-time = "2026-03-02T12:53:10.01Z" }, + { url = "https://files.pythonhosted.org/packages/33/7a/2bfc9e9341d50813674d3db6425ac4cb963764bffdf589774f94c0cbf852/confluent_kafka-2.13.2-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:f09adb42fb898a0b3a88b02e77bee472e93f758258945386c77864016b4e4efc", size = 3724554, upload-time = "2026-03-02T12:53:11.682Z" }, + { url = "https://files.pythonhosted.org/packages/cf/bb/0d0cdad1763044f3e06bea52c3332256b17f3e64c04a8214ee217fc68ab0/confluent_kafka-2.13.2-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:fa3be1fe231e06b2c7501fa3641b30ea90ea17be79ca89806eef22ff34ed106c", size = 3981002, upload-time = "2026-03-02T12:53:13.399Z" }, + { url = "https://files.pythonhosted.org/packages/69/65/361ace93de20ab5d83dc0d108389b29f4549f478e0b8aa0f19baf597c0f0/confluent_kafka-2.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:a8d1e0721de378034ecc928b47238272b56bf20af5dd504233bcb93ce07a38a6", size = 4275836, upload-time = "2026-03-02T12:53:14.703Z" }, ] [[package]] @@ -3169,7 +3165,7 @@ instruments = [ [package.metadata] requires-dist = [ - { name = "confluent-kafka", marker = "extra == 'instruments'", specifier = ">=1.8.2,<=2.13.0" }, + { name = "confluent-kafka", marker = "extra == 'instruments'", specifier = ">=1.8.2,<3.0.0" }, { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, From 196d088e1371792b1544107448f2f9b88fd7e578 Mon Sep 17 00:00:00 2001 From: Mike Goldsmith Date: Tue, 10 Mar 2026 13:36:26 +0000 Subject: [PATCH 09/78] ci: increase stale action operations-per-run to 500 (#4312) * increase stale action operations-per-run to 500 Assisted-by: Claude Sonnet 4.6 * add changelog entry for stale ops-per-run increase Assisted-by: Claude Sonnet 4.6 * add TODO to revert once backlog is cleaned up --------- Co-authored-by: Riccardo Magliocchetti --- .github/workflows/stale.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index f212b5e035a..b30c6a571ce 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -33,3 +33,5 @@ jobs: This PR has been closed due to inactivity. Please reopen if you would like to continue working on it. exempt-pr-labels: "hold,WIP,blocked-by-spec,do not merge" + # TODO: Revert back to default of 30 after we have cleared the backlog of stale PRs. + operations-per-run: 500 From b44ca58008b852e5de0501b3ed76243d51f592aa Mon Sep 17 00:00:00 2001 From: Adam Malcontenti-Wilson Date: Thu, 12 Mar 2026 05:33:50 +1100 Subject: [PATCH 10/78] [openai-agents] Populate instructions and tool definitions from Response obj (#4196) --- .../CHANGELOG.md | 2 + .../openai_agents/span_processor.py | 26 +++++++++++ .../tests/test_tracer.py | 46 +++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md index 550c74b9d03..90f8c11e01a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4229](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4229)) - Document official package metadata and README for the OpenAI Agents instrumentation. ([#3859](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3859)) +- Populate instructions and tool definitions from Response obj. + ([#4196](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4196)) ## Version 0.1.0 (2025-10-15) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py index d8b28279edf..74be6637010 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py @@ -1056,10 +1056,20 @@ def _build_content_payload(self, span: Span[Any]) -> ContentPayload: elif _is_instance_of(span_data, ResponseSpanData): span_input = getattr(span_data, "input", None) + response_obj = getattr(span_data, "response", None) if capture_messages and span_input: payload.input_messages = ( self._normalize_messages_to_role_parts(span_input) ) + + if ( + capture_system + and response_obj + and hasattr(response_obj, "instructions") + ): + payload.system_instructions = self._normalize_to_text_parts( + response_obj.instructions + ) if capture_system and span_input: sys_instr = self._collect_system_instructions(span_input) if sys_instr: @@ -2016,6 +2026,22 @@ def _get_attributes_from_response_span_data( if output_tokens is not None: yield GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens + # Tool definitions from response + if self._capture_tool_definitions and hasattr( + span_data.response, "tools" + ): + yield ( + GEN_AI_TOOL_DEFINITIONS, + safe_json_dumps( + list( + map( + lambda tool: tool.to_dict(), + span_data.response.tools, + ) + ) + ), + ) + # Input/output messages if ( self.include_sensitive_data diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py index a2e8143b0dd..5c62fd492e2 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py @@ -25,6 +25,7 @@ set_trace_processors, trace, ) +from openai.types.responses import FunctionTool # noqa: E402 from opentelemetry.instrumentation.openai_agents import ( # noqa: E402 OpenAIAgentsInstrumentor, @@ -62,6 +63,9 @@ GEN_AI_OUTPUT_MESSAGES = getattr( GenAI, "GEN_AI_OUTPUT_MESSAGES", "gen_ai.output.messages" ) +GEN_AI_TOOL_DEFINITIONS = getattr( + GenAI, "GEN_AI_TOOL_DEFINITIONS", "gen_ai.tool.definitions" +) def _instrument_with_provider(**instrument_kwargs): @@ -478,8 +482,26 @@ def __init__(self, input_tokens: int, output_tokens: int) -> None: class _Response: def __init__(self) -> None: self.id = "resp-123" + self.instructions = "You are a helpful assistant." self.model = "gpt-4o-mini" self.usage = _Usage(42, 9) + self.tools = [ + FunctionTool( + name="get_current_weather", + type="function", + description="Get the current weather in a given location", + parameters={ + "type": "object", + "properties": { + "location": { + "title": "Location", + "type": "string", + }, + }, + "required": ["location"], + }, + ) + ] self.output = [{"finish_reason": "stop"}] try: @@ -507,6 +529,30 @@ def __init__(self) -> None: assert response.attributes[GenAI.GEN_AI_RESPONSE_FINISH_REASONS] == ( "stop", ) + + system_instructions = json.loads( + response.attributes[GenAI.GEN_AI_SYSTEM_INSTRUCTIONS] + ) + assert system_instructions == [ + {"type": "text", "content": "You are a helpful assistant."} + ] + tool_definitions = json.loads( + response.attributes[GEN_AI_TOOL_DEFINITIONS] + ) + assert tool_definitions == [ + { + "type": "function", + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": {"title": "Location", "type": "string"}, + }, + "required": ["location"], + }, + } + ] finally: instrumentor.uninstrument() exporter.clear() From 7d42bd11305d0bbc2bc1b83ce8beea78db57dcc1 Mon Sep 17 00:00:00 2001 From: Tobias Macey Date: Wed, 11 Mar 2026 17:10:21 -0400 Subject: [PATCH 11/78] Add support for wrapt 2.x (#4203) * Add support for wrapt 2.x - Update wrapt version constraint from '>=1.0.0, <2.0.0' to '>=1.0.0' in all affected packages - Replace ObjectProxy with BaseObjectProxy where iteration support is not needed - Add fallback import for wrapt 1.x compatibility (ObjectProxy as BaseObjectProxy) - Keep ObjectProxy usage in classes that implement __iter__ (botocore, aiopg) - Update CHANGELOG.md This change maintains backward compatibility with wrapt 1.x while enabling support for wrapt 2.x. BaseObjectProxy is the new base class in wrapt 2.x, while ObjectProxy is now a subclass that adds __iter__() support. Fixes #3903 Related to #3930 and #4082 * Restructure wrapt test requirements - Remove wrapt from base test-requirements.txt (installed via pyproject.toml) - Remove Deprecated from base test-requirements.txt (version conflicts with wrapt 2.x) - Create test-requirements-wrapt1.txt with wrapt<2.0.0 and Deprecated==1.2.14 - Create test-requirements-wrapt2.txt with wrapt>=2.0.0 and Deprecated>=1.2.18 - Update tox.ini to use requirements files instead of factor-based deps - Add Deprecated to lint environment deps This follows the pattern used by other packages (botocore, httpx) and resolves dependency conflicts where Deprecated 1.2.14 requires wrapt<2. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: Resolve conflicts and add Wrapt 3 as upper bound * Add wrapt 1.x/2.x test matrix for all ObjectProxy-using instrumentations Extend the wrapt1/wrapt2 test matrix to all instrumentations that use wrapt.ObjectProxy or wrapt.BaseObjectProxy: botocore, dbapi, grpc, pika, aiopg, httpx, and asyncpg. Changes: - tox.ini: Add {wrapt1,wrapt2} factor to envlist for all 7 packages; update deps to reference per-version test-requirements files - botocore/pyproject.toml: Add missing wrapt dependency (>= 1.0.0, < 3.0.0) - All base test-requirements files: Remove pinned wrapt== and Deprecated== - New test-requirements-wrapt1.txt / test-requirements-wrapt2.txt files for each package (using Deprecated>=1.2.18 for wrapt2 to avoid conflict with Deprecated==1.2.14 which requires wrapt<2) - Regenerate GitHub Actions workflows (including new test_3.yml due to expanded job count) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CI failures: ruff formatting and lint wrapt version pin - utils.py: reformat multi-condition if statement to satisfy ruff line length requirement (fixes generate/precommit CI jobs) - tox.ini: pin wrapt>=1.0.0,<2.0.0 for lint envs of botocore, dbapi, grpc, and sio-pika; with wrapt 1.x removed from base test-requirements, lint envs were getting wrapt 2.x which caused pylint no-member errors on __wrapped__ (a C-extension attribute not visible to static analysis) Also add Deprecated==1.2.14 to same lint envs for consistency Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix remaining CI failures: unused imports and uv.lock - dbapi/__init__.py: remove unused bare 'import wrapt' (F401); the compat shim imports BaseObjectProxy directly from wrapt - grpc/_aio_server.py: remove unused 'import wrapt' (F401) and fix import ordering (I001) flagged by ruff pre-commit hook - uv.lock: regenerate after adding wrapt dependency to botocore pyproject.toml Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix aiopg lint wrapt pin, uv.lock format, and ruff blank lines - tox.ini: pin wrapt>=1.0.0,<2.0.0 + Deprecated==1.2.14 for lint-instrumentation-aiopg; aiopg source uses __wrapped__ heavily and pylint's no-member error appeared when wrapt 2.x was installed - uv.lock: regenerate using pre-commit hook (uv v0.9.30) to fix trailing-slash format on registry URLs - httpx/test_httpx_integration.py: add blank line before try/except block (ruff I001/E303 formatting fix) - pika/utils.py: add blank line before try/except block (same ruff fix) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix pylint E0611: disable no-name-in-module for BaseObjectProxy compat shim pylint with wrapt 1.x installed reports E0611 ('No name BaseObjectProxy in module wrapt') when it sees the try/except ImportError compat shim, even though the except branch provides a fallback. Add a per-line pylint disable comment to suppress this false positive. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix asyncpg test: use BaseObjectProxy compat shim for wrapt 2.x In wrapt 2.x, BoundFunctionWrapper no longer subclasses ObjectProxy (it subclasses BaseObjectProxy instead). Update the test to use the compat shim so isinstance checks pass with both wrapt 1.x and 2.x. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review comments: add wrapt 2.0.0+ comments and fix CHANGELOG - Add '# wrapt 2.0.0+' comment above BaseObjectProxy import in all try/except compat shim blocks to clarify why the pattern is used - Fix CHANGELOG.md PR link from #XXXX to #4203 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Riccardo Magliocchetti * chore: Update changelog and workflows * Apply suggestions from code review Co-authored-by: Riccardo Magliocchetti * fix: Update workflows again * Apply suggestions from code review Co-authored-by: Riccardo Magliocchetti * Remove Deprecated version pins from test-requirements and tox.ini Deprecated>=1.2.14 was pinned because Deprecated==1.2.14 requires wrapt<2. Since pip automatically resolves compatible versions based on the wrapt constraint in each test env, explicit Deprecated pins are unnecessary. Remove them from all test-requirements-wrapt*.txt files and from lint env deps in tox.ini. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove stale .orig file leftover from rebase Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move lint env wrapt pins from tox.ini into test-requirements files All dependencies should be managed via requirements.txt files rather than inline in tox.ini. Move wrapt>=1.0.0,<2.0.0 pins for lint environments into their respective test-requirements files: - instrumentation-grpc/test-requirements-1.txt - instrumentation-botocore/test-requirements-1.txt - instrumentation-dbapi/test-requirements.txt - instrumentation-aiopg/test-requirements.txt Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply suggestions from code review * Update instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt * Update instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt * Update instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt * Update instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt * Address latest PR feedback: botocore compat shim, exact wrapt versions, lint env refs - botocore/bedrock_utils.py: apply BaseObjectProxy compat shim to ConverseStreamWrapper and InvokeModelWithResponseStreamWrapper (both classes define __iter__ so BaseObjectProxy is correct) - All test-requirements-wrapt1.txt: pin wrapt==1.17.3 (exact version) - All test-requirements-wrapt2.txt: pin wrapt==2.1.2 (exact version) - tox.ini lint envs: switch to -wrapt2.txt files so lint runs with wrapt 2.x; remove wrapt pin from base test-requirements files (grpc/test-requirements-1.txt, botocore/test-requirements-1.txt, dbapi/test-requirements.txt, aiopg/test-requirements.txt) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: add pylint disable=no-member for __wrapped__ and abstract-method usages Add pylint: disable=no-member to all class definitions and usages of __wrapped__ that are invisible to pylint when using wrapt's C extension proxy types (BaseObjectProxy/ObjectProxy). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .github/workflows/core_contrib_test_0.yml | 432 ++- .github/workflows/test_0.yml | 1350 ++++----- .github/workflows/test_1.yml | 2204 +++++++------- .github/workflows/test_2.yml | 2686 +++++++++++------ .github/workflows/test_3.yml | 413 +++ CHANGELOG.md | 4 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../aiopg/aiopg_integration.py | 8 +- .../test-requirements-wrapt1.txt | 2 + .../test-requirements-wrapt2.txt | 2 + .../test-requirements.txt | 2 - .../tests/test_aiopg_integration.py | 4 +- .../pyproject.toml | 2 +- .../test-requirements-wrapt1.txt | 2 + .../test-requirements-wrapt2.txt | 2 + .../test-requirements.txt | 2 - .../tests/test_asyncpg_wrapper.py | 9 +- .../pyproject.toml | 2 +- .../pyproject.toml | 1 + .../botocore/extensions/bedrock_utils.py | 19 +- .../test-requirements-0-wrapt1.txt | 2 + .../test-requirements-0-wrapt2.txt | 2 + .../test-requirements-0.txt | 2 - .../test-requirements-1-wrapt1.txt | 2 + .../test-requirements-1-wrapt2.txt | 2 + .../test-requirements-1.txt | 2 - .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../instrumentation/dbapi/__init__.py | 23 +- .../test-requirements-wrapt1.txt | 2 + .../test-requirements-wrapt2.txt | 2 + .../test-requirements.txt | 2 - .../tests/test_dbapi_integration.py | 6 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../instrumentation/grpc/_aio_server.py | 11 +- .../test-requirements-0-wrapt1.txt | 2 + .../test-requirements-0-wrapt2.txt | 2 + .../test-requirements-0.txt | 2 - .../test-requirements-1-wrapt1.txt | 2 + .../test-requirements-1-wrapt2.txt | 2 + .../test-requirements-1.txt | 2 - .../pyproject.toml | 2 +- .../test-requirements-0-wrapt1.txt | 2 + .../test-requirements-0-wrapt2.txt | 2 + .../test-requirements-0.txt | 2 - .../test-requirements-1-wrapt1.txt | 2 + .../test-requirements-1-wrapt2.txt | 2 + .../test-requirements-1.txt | 2 - .../tests/test_httpx_integration.py | 17 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../instrumentation/pika/utils.py | 11 +- .../test-requirements-0-wrapt1.txt | 2 + .../test-requirements-0-wrapt2.txt | 2 + .../test-requirements-0.txt | 2 - .../test-requirements-1-wrapt1.txt | 2 + .../test-requirements-1-wrapt2.txt | 2 + .../test-requirements-1.txt | 2 - .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- .../pyproject.toml | 2 +- opentelemetry-instrumentation/pyproject.toml | 2 +- .../opentelemetry/instrumentation/utils.py | 12 +- .../test-requirements-wrapt1.txt | 2 + .../test-requirements-wrapt2.txt | 2 + .../test-requirements.txt | 2 - .../tests/test_utils.py | 32 +- .../pyproject.toml | 2 +- tox.ini | 76 +- uv.lock | 42 +- 77 files changed, 4624 insertions(+), 2850 deletions(-) create mode 100644 .github/workflows/test_3.yml create mode 100644 instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt1.txt create mode 100644 instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt2.txt create mode 100644 opentelemetry-instrumentation/test-requirements-wrapt1.txt create mode 100644 opentelemetry-instrumentation/test-requirements-wrapt2.txt diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index 6cc751461a5..47d0196cd04 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -447,8 +447,8 @@ jobs: - name: Run tests run: tox -e py39-test-distro -- -ra - py39-test-opentelemetry-instrumentation: - name: opentelemetry-instrumentation + py39-test-opentelemetry-instrumentation-wrapt1: + name: opentelemetry-instrumentation-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -475,7 +475,37 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation -- -ra + run: tox -e py39-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py39-test-opentelemetry-instrumentation-wrapt2: + name: opentelemetry-instrumentation-wrapt2 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opentelemetry-instrumentation-wrapt2 -- -ra py39-test-instrumentation-aiohttp-client: name: instrumentation-aiohttp-client @@ -537,8 +567,8 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-aiohttp-server -- -ra - py39-test-instrumentation-aiopg: - name: instrumentation-aiopg + py39-test-instrumentation-aiopg-wrapt1: + name: instrumentation-aiopg-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -565,7 +595,37 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiopg -- -ra + run: tox -e py39-test-instrumentation-aiopg-wrapt1 -- -ra + + py39-test-instrumentation-aiopg-wrapt2: + name: instrumentation-aiopg-wrapt2 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aiopg-wrapt2 -- -ra py39-test-instrumentation-aws-lambda: name: instrumentation-aws-lambda @@ -597,8 +657,38 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-botocore-0: - name: instrumentation-botocore-0 + py39-test-instrumentation-botocore-0-wrapt1: + name: instrumentation-botocore-0-wrapt1 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-0-wrapt1 -- -ra + + py39-test-instrumentation-botocore-0-wrapt2: + name: instrumentation-botocore-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -625,10 +715,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0 -- -ra + run: tox -e py39-test-instrumentation-botocore-0-wrapt2 -- -ra - py39-test-instrumentation-botocore-1: - name: instrumentation-botocore-1 + py39-test-instrumentation-botocore-1-wrapt1: + name: instrumentation-botocore-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -655,7 +745,37 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1 -- -ra + run: tox -e py39-test-instrumentation-botocore-1-wrapt1 -- -ra + + py39-test-instrumentation-botocore-1-wrapt2: + name: instrumentation-botocore-1-wrapt2 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra py39-test-instrumentation-boto3sqs: name: instrumentation-boto3sqs @@ -777,8 +897,8 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-django-2 -- -ra - py39-test-instrumentation-dbapi: - name: instrumentation-dbapi + py39-test-instrumentation-dbapi-wrapt1: + name: instrumentation-dbapi-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -805,7 +925,37 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi -- -ra + run: tox -e py39-test-instrumentation-dbapi-wrapt1 -- -ra + + py39-test-instrumentation-dbapi-wrapt2: + name: instrumentation-dbapi-wrapt2 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra py39-test-instrumentation-boto: name: instrumentation-boto @@ -2037,8 +2187,38 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-asgi -- -ra - py39-test-instrumentation-asyncpg: - name: instrumentation-asyncpg + py39-test-instrumentation-asyncpg-wrapt1: + name: instrumentation-asyncpg-wrapt1 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-asyncpg-wrapt1 -- -ra + + py39-test-instrumentation-asyncpg-wrapt2: + name: instrumentation-asyncpg-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2065,7 +2245,7 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg -- -ra + run: tox -e py39-test-instrumentation-asyncpg-wrapt2 -- -ra py39-test-instrumentation-sqlite3: name: instrumentation-sqlite3 @@ -2127,8 +2307,8 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-wsgi -- -ra - py39-test-instrumentation-grpc-0: - name: instrumentation-grpc-0 + py39-test-instrumentation-grpc-0-wrapt1: + name: instrumentation-grpc-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2155,10 +2335,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0 -- -ra + run: tox -e py39-test-instrumentation-grpc-0-wrapt1 -- -ra - py39-test-instrumentation-grpc-1: - name: instrumentation-grpc-1 + py39-test-instrumentation-grpc-0-wrapt2: + name: instrumentation-grpc-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2185,7 +2365,67 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1 -- -ra + run: tox -e py39-test-instrumentation-grpc-0-wrapt2 -- -ra + + py39-test-instrumentation-grpc-1-wrapt1: + name: instrumentation-grpc-1-wrapt1 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-grpc-1-wrapt1 -- -ra + + py39-test-instrumentation-grpc-1-wrapt2: + name: instrumentation-grpc-1-wrapt2 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-grpc-1-wrapt2 -- -ra py39-test-instrumentation-sqlalchemy-1: name: instrumentation-sqlalchemy-1 @@ -2457,8 +2697,38 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-tortoiseorm -- -ra - py39-test-instrumentation-httpx-0: - name: instrumentation-httpx-0 + py39-test-instrumentation-httpx-0-wrapt1: + name: instrumentation-httpx-0-wrapt1 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-httpx-0-wrapt1 -- -ra + + py39-test-instrumentation-httpx-0-wrapt2: + name: instrumentation-httpx-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2485,10 +2755,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0 -- -ra + run: tox -e py39-test-instrumentation-httpx-0-wrapt2 -- -ra - py39-test-instrumentation-httpx-1: - name: instrumentation-httpx-1 + py39-test-instrumentation-httpx-1-wrapt1: + name: instrumentation-httpx-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2515,7 +2785,37 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1 -- -ra + run: tox -e py39-test-instrumentation-httpx-1-wrapt1 -- -ra + + py39-test-instrumentation-httpx-1-wrapt2: + name: instrumentation-httpx-1-wrapt2 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-httpx-1-wrapt2 -- -ra py39-test-util-http: name: util-http @@ -2697,8 +2997,68 @@ jobs: - name: Run tests run: tox -e py39-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-0: - name: instrumentation-sio-pika-0 + py39-test-instrumentation-sio-pika-0-wrapt1: + name: instrumentation-sio-pika-0-wrapt1 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-0-wrapt1 -- -ra + + py39-test-instrumentation-sio-pika-0-wrapt2: + name: instrumentation-sio-pika-0-wrapt2 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + py39-test-instrumentation-sio-pika-1-wrapt1: + name: instrumentation-sio-pika-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2725,10 +3085,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py39-test-instrumentation-sio-pika-1-wrapt1 -- -ra - py39-test-instrumentation-sio-pika-1: - name: instrumentation-sio-pika-1 + py39-test-instrumentation-sio-pika-1-wrapt2: + name: instrumentation-sio-pika-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2755,7 +3115,7 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py39-test-instrumentation-sio-pika-1-wrapt2 -- -ra py39-test-instrumentation-aio-pika-0: name: instrumentation-aio-pika-0 diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index f057dbc7b96..a8442aeecfd 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -2122,8 +2122,8 @@ jobs: - name: Run tests run: tox -e pypy3-test-distro -- -ra - py39-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.9 Ubuntu + py39-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2139,10 +2139,48 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation -- -ra + run: tox -e py39-test-opentelemetry-instrumentation-wrapt1 -- -ra - py310-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.10 Ubuntu + py39-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py310-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py310-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2158,10 +2196,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-opentelemetry-instrumentation -- -ra + run: tox -e py310-test-opentelemetry-instrumentation-wrapt2 -- -ra - py311-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.11 Ubuntu + py311-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2177,10 +2215,48 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-opentelemetry-instrumentation -- -ra + run: tox -e py311-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py311-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py312-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opentelemetry-instrumentation-wrapt1 -- -ra - py312-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.12 Ubuntu + py312-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2196,10 +2272,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-opentelemetry-instrumentation -- -ra + run: tox -e py312-test-opentelemetry-instrumentation-wrapt2 -- -ra - py313-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.13 Ubuntu + py313-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2215,10 +2291,48 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-opentelemetry-instrumentation -- -ra + run: tox -e py313-test-opentelemetry-instrumentation-wrapt1 -- -ra - py314-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation 3.14 Ubuntu + py313-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py314-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py314-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2234,10 +2348,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-opentelemetry-instrumentation -- -ra + run: tox -e py314-test-opentelemetry-instrumentation-wrapt2 -- -ra - pypy3-test-opentelemetry-instrumentation_ubuntu-latest: - name: opentelemetry-instrumentation pypy-3.9 Ubuntu + pypy3-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2253,7 +2367,7 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-opentelemetry-instrumentation -- -ra + run: tox -e pypy3-test-opentelemetry-instrumentation-wrapt2 -- -ra py39-test-instrumentation-aiohttp-client_ubuntu-latest: name: instrumentation-aiohttp-client 3.9 Ubuntu @@ -2521,8 +2635,8 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra - py39-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.9 Ubuntu + py39-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2538,10 +2652,48 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiopg -- -ra + run: tox -e py39-test-instrumentation-aiopg-wrapt1 -- -ra + + py39-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aiopg-wrapt2 -- -ra + + py310-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aiopg-wrapt1 -- -ra - py310-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.10 Ubuntu + py310-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2557,10 +2709,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-aiopg -- -ra + run: tox -e py310-test-instrumentation-aiopg-wrapt2 -- -ra - py311-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.11 Ubuntu + py311-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2576,10 +2728,48 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-aiopg -- -ra + run: tox -e py311-test-instrumentation-aiopg-wrapt1 -- -ra - py312-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.12 Ubuntu + py311-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aiopg-wrapt2 -- -ra + + py312-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aiopg-wrapt1 -- -ra + + py312-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2595,10 +2785,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-aiopg -- -ra + run: tox -e py312-test-instrumentation-aiopg-wrapt2 -- -ra - py313-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.13 Ubuntu + py313-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2614,10 +2804,48 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-aiopg -- -ra + run: tox -e py313-test-instrumentation-aiopg-wrapt1 -- -ra + + py313-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aiopg-wrapt2 -- -ra + + py314-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aiopg-wrapt1 -- -ra - py314-test-instrumentation-aiopg_ubuntu-latest: - name: instrumentation-aiopg 3.14 Ubuntu + py314-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2633,7 +2861,7 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-aiopg -- -ra + run: tox -e py314-test-instrumentation-aiopg-wrapt2 -- -ra py39-test-instrumentation-aws-lambda_ubuntu-latest: name: instrumentation-aws-lambda 3.9 Ubuntu @@ -2768,8 +2996,8 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-botocore-0_ubuntu-latest: - name: instrumentation-botocore-0 3.9 Ubuntu + py39-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2785,10 +3013,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0 -- -ra + run: tox -e py39-test-instrumentation-botocore-0-wrapt1 -- -ra - py39-test-instrumentation-botocore-1_ubuntu-latest: - name: instrumentation-botocore-1 3.9 Ubuntu + py39-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2804,257 +3032,257 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1 -- -ra + run: tox -e py39-test-instrumentation-botocore-0-wrapt2 -- -ra - py310-test-instrumentation-botocore-0_ubuntu-latest: - name: instrumentation-botocore-0 3.10 Ubuntu + py39-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-botocore-0 -- -ra + run: tox -e py39-test-instrumentation-botocore-1-wrapt1 -- -ra - py310-test-instrumentation-botocore-1_ubuntu-latest: - name: instrumentation-botocore-1 3.10 Ubuntu + py39-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-botocore-1 -- -ra + run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra - py311-test-instrumentation-botocore-0_ubuntu-latest: - name: instrumentation-botocore-0 3.11 Ubuntu + py310-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-botocore-0 -- -ra + run: tox -e py310-test-instrumentation-botocore-0-wrapt1 -- -ra - py311-test-instrumentation-botocore-1_ubuntu-latest: - name: instrumentation-botocore-1 3.11 Ubuntu + py310-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-botocore-1 -- -ra + run: tox -e py310-test-instrumentation-botocore-0-wrapt2 -- -ra - py312-test-instrumentation-botocore-0_ubuntu-latest: - name: instrumentation-botocore-0 3.12 Ubuntu + py310-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-botocore-0 -- -ra + run: tox -e py310-test-instrumentation-botocore-1-wrapt1 -- -ra - py312-test-instrumentation-botocore-1_ubuntu-latest: - name: instrumentation-botocore-1 3.12 Ubuntu + py310-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-botocore-1 -- -ra + run: tox -e py310-test-instrumentation-botocore-1-wrapt2 -- -ra - py313-test-instrumentation-botocore-0_ubuntu-latest: - name: instrumentation-botocore-0 3.13 Ubuntu + py311-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-botocore-0 -- -ra + run: tox -e py311-test-instrumentation-botocore-0-wrapt1 -- -ra - py313-test-instrumentation-botocore-1_ubuntu-latest: - name: instrumentation-botocore-1 3.13 Ubuntu + py311-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-botocore-1 -- -ra + run: tox -e py311-test-instrumentation-botocore-0-wrapt2 -- -ra - py314-test-instrumentation-botocore-0_ubuntu-latest: - name: instrumentation-botocore-0 3.14 Ubuntu + py311-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-botocore-0 -- -ra + run: tox -e py311-test-instrumentation-botocore-1-wrapt1 -- -ra - py314-test-instrumentation-botocore-1_ubuntu-latest: - name: instrumentation-botocore-1 3.14 Ubuntu + py311-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-botocore-1 -- -ra + run: tox -e py311-test-instrumentation-botocore-1-wrapt2 -- -ra - py39-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.9 Ubuntu + py312-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-boto3sqs -- -ra + run: tox -e py312-test-instrumentation-botocore-0-wrapt1 -- -ra - py310-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.10 Ubuntu + py312-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-boto3sqs -- -ra + run: tox -e py312-test-instrumentation-botocore-0-wrapt2 -- -ra - py311-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.11 Ubuntu + py312-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-boto3sqs -- -ra + run: tox -e py312-test-instrumentation-botocore-1-wrapt1 -- -ra - py312-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.12 Ubuntu + py312-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3070,10 +3298,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-boto3sqs -- -ra + run: tox -e py312-test-instrumentation-botocore-1-wrapt2 -- -ra - py313-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.13 Ubuntu + py313-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3089,200 +3317,200 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-boto3sqs -- -ra + run: tox -e py313-test-instrumentation-botocore-0-wrapt1 -- -ra - py314-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.14 Ubuntu + py313-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-boto3sqs -- -ra + run: tox -e py313-test-instrumentation-botocore-0-wrapt2 -- -ra - pypy3-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs pypy-3.9 Ubuntu + py313-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra + run: tox -e py313-test-instrumentation-botocore-1-wrapt1 -- -ra - py39-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 3.9 Ubuntu + py313-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-0 -- -ra + run: tox -e py313-test-instrumentation-botocore-1-wrapt2 -- -ra - py39-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.9 Ubuntu + py314-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-1 -- -ra + run: tox -e py314-test-instrumentation-botocore-0-wrapt1 -- -ra - py39-test-instrumentation-django-2_ubuntu-latest: - name: instrumentation-django-2 3.9 Ubuntu + py314-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-2 -- -ra + run: tox -e py314-test-instrumentation-botocore-0-wrapt2 -- -ra - py310-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.10 Ubuntu + py314-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-django-1 -- -ra + run: tox -e py314-test-instrumentation-botocore-1-wrapt1 -- -ra - py310-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.10 Ubuntu + py314-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-django-3 -- -ra + run: tox -e py314-test-instrumentation-botocore-1-wrapt2 -- -ra - py311-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.11 Ubuntu + py39-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-django-1 -- -ra + run: tox -e py39-test-instrumentation-boto3sqs -- -ra - py311-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.11 Ubuntu + py310-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-django-3 -- -ra + run: tox -e py310-test-instrumentation-boto3sqs -- -ra - py312-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.12 Ubuntu + py311-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-django-1 -- -ra + run: tox -e py311-test-instrumentation-boto3sqs -- -ra - py312-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.12 Ubuntu + py312-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3298,10 +3526,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-django-3 -- -ra + run: tox -e py312-test-instrumentation-boto3sqs -- -ra - py313-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.13 Ubuntu + py313-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3317,10 +3545,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-django-3 -- -ra + run: tox -e py313-test-instrumentation-boto3sqs -- -ra - py314-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.14 Ubuntu + py314-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3336,10 +3564,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-django-3 -- -ra + run: tox -e py314-test-instrumentation-boto3sqs -- -ra - pypy3-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 pypy-3.9 Ubuntu + pypy3-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3355,29 +3583,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-django-0 -- -ra + run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra - pypy3-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 pypy-3.9 Ubuntu + py39-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-django-1 -- -ra + run: tox -e py39-test-instrumentation-django-0 -- -ra - py39-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.9 Ubuntu + py39-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3393,371 +3621,352 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi -- -ra + run: tox -e py39-test-instrumentation-django-1 -- -ra - py310-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.10 Ubuntu + py39-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-dbapi -- -ra + run: tox -e py39-test-instrumentation-django-2 -- -ra - py311-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.11 Ubuntu + py310-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-dbapi -- -ra + run: tox -e py310-test-instrumentation-django-1 -- -ra - py312-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.12 Ubuntu + py310-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-dbapi -- -ra + run: tox -e py310-test-instrumentation-django-3 -- -ra - py313-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.13 Ubuntu + py311-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-dbapi -- -ra + run: tox -e py311-test-instrumentation-django-1 -- -ra - py314-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi 3.14 Ubuntu + py311-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-dbapi -- -ra + run: tox -e py311-test-instrumentation-django-3 -- -ra - pypy3-test-instrumentation-dbapi_ubuntu-latest: - name: instrumentation-dbapi pypy-3.9 Ubuntu + py312-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-dbapi -- -ra + run: tox -e py312-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.9 Ubuntu + py312-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-boto -- -ra + run: tox -e py312-test-instrumentation-django-3 -- -ra - py310-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.10 Ubuntu + py313-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-boto -- -ra + run: tox -e py313-test-instrumentation-django-3 -- -ra - py311-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.11 Ubuntu + py314-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-boto -- -ra + run: tox -e py314-test-instrumentation-django-3 -- -ra - py39-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.9 Ubuntu + pypy3-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncclick -- -ra + run: tox -e pypy3-test-instrumentation-django-0 -- -ra - py310-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.10 Ubuntu + pypy3-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-asyncclick -- -ra + run: tox -e pypy3-test-instrumentation-django-1 -- -ra - py311-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.11 Ubuntu + py39-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-asyncclick -- -ra + run: tox -e py39-test-instrumentation-dbapi-wrapt1 -- -ra - py312-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.12 Ubuntu + py39-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-asyncclick -- -ra + run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra - py313-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.13 Ubuntu + py310-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-asyncclick -- -ra + run: tox -e py310-test-instrumentation-dbapi-wrapt1 -- -ra - py314-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.14 Ubuntu + py310-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-asyncclick -- -ra + run: tox -e py310-test-instrumentation-dbapi-wrapt2 -- -ra - pypy3-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick pypy-3.9 Ubuntu + py311-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-asyncclick -- -ra + run: tox -e py311-test-instrumentation-dbapi-wrapt1 -- -ra - py39-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.9 Ubuntu + py311-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-click -- -ra + run: tox -e py311-test-instrumentation-dbapi-wrapt2 -- -ra - py310-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.10 Ubuntu + py312-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-click -- -ra - - py311-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-click -- -ra + run: tox -e py312-test-instrumentation-dbapi-wrapt1 -- -ra - py312-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.12 Ubuntu + py312-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3773,10 +3982,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-click -- -ra + run: tox -e py312-test-instrumentation-dbapi-wrapt2 -- -ra - py313-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.13 Ubuntu + py313-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3792,86 +4001,86 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-click -- -ra + run: tox -e py313-test-instrumentation-dbapi-wrapt1 -- -ra - py314-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.14 Ubuntu + py313-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-click -- -ra + run: tox -e py313-test-instrumentation-dbapi-wrapt2 -- -ra - pypy3-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click pypy-3.9 Ubuntu + py314-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-click -- -ra + run: tox -e py314-test-instrumentation-dbapi-wrapt1 -- -ra - py39-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.9 Ubuntu + py314-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py314-test-instrumentation-dbapi-wrapt2 -- -ra - py39-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.9 Ubuntu + pypy3-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e pypy3-test-instrumentation-dbapi-wrapt2 -- -ra - py39-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.9 Ubuntu + py39-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3887,48 +4096,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra - - py310-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra - - py310-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py39-test-instrumentation-boto -- -ra - py310-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.10 Ubuntu + py310-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3944,29 +4115,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra - - py311-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py310-test-instrumentation-boto -- -ra - py311-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.11 Ubuntu + py311-test-instrumentation-boto_ubuntu-latest: + name: instrumentation-boto 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3982,67 +4134,67 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py311-test-instrumentation-boto -- -ra - py311-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.11 Ubuntu + py39-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py39-test-instrumentation-asyncclick -- -ra - py312-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.12 Ubuntu + py310-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py310-test-instrumentation-asyncclick -- -ra - py312-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.12 Ubuntu + py311-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py311-test-instrumentation-asyncclick -- -ra - py312-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.12 Ubuntu + py312-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4058,10 +4210,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py312-test-instrumentation-asyncclick -- -ra - py313-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.13 Ubuntu + py313-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4077,181 +4229,181 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py313-test-instrumentation-asyncclick -- -ra - py313-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.13 Ubuntu + py314-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py314-test-instrumentation-asyncclick -- -ra - py313-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.13 Ubuntu + pypy3-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e pypy3-test-instrumentation-asyncclick -- -ra - py314-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.14 Ubuntu + py39-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py39-test-instrumentation-click -- -ra - py314-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.14 Ubuntu + py310-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py310-test-instrumentation-click -- -ra - py314-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.14 Ubuntu + py311-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py311-test-instrumentation-click -- -ra - pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 pypy-3.9 Ubuntu + py312-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py312-test-instrumentation-click -- -ra - pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 pypy-3.9 Ubuntu + py313-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py313-test-instrumentation-click -- -ra - pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu + py314-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py314-test-instrumentation-click -- -ra - py39-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.9 Ubuntu + pypy3-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra + run: tox -e pypy3-test-instrumentation-click -- -ra - py39-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.9 Ubuntu + py39-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4267,10 +4419,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra - py39-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.9 Ubuntu + py39-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4286,10 +4438,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-2 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra - py39-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.9 Ubuntu + py39-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4305,29 +4457,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-3 -- -ra - - py310-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-falcon-1 -- -ra + run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra - py310-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.10 Ubuntu + py310-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4343,10 +4476,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-falcon-2 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra - py310-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.10 Ubuntu + py310-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4362,10 +4495,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-falcon-3 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra - py310-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.10 Ubuntu + py310-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4381,29 +4514,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-falcon-4 -- -ra - - py311-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-falcon-1 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra - py311-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.11 Ubuntu + py311-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4419,10 +4533,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-falcon-2 -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra - py311-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.11 Ubuntu + py311-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4438,10 +4552,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-falcon-3 -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra - py311-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.11 Ubuntu + py311-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4457,10 +4571,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-falcon-4 -- -ra + run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra - py312-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.12 Ubuntu + py312-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4476,10 +4590,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-falcon-1 -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra - py312-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.12 Ubuntu + py312-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4495,10 +4609,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-falcon-2 -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra - py312-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.12 Ubuntu + py312-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4514,29 +4628,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-falcon-3 -- -ra + run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra - py312-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.12 Ubuntu + py313-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-falcon-4 -- -ra + run: tox -e py313-test-instrumentation-elasticsearch-0 -- -ra - py313-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.13 Ubuntu + py313-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4552,86 +4666,86 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-falcon-4 -- -ra + run: tox -e py313-test-instrumentation-elasticsearch-1 -- -ra - py314-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.14 Ubuntu + py313-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-falcon-4 -- -ra + run: tox -e py313-test-instrumentation-elasticsearch-2 -- -ra - pypy3-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 pypy-3.9 Ubuntu + py314-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra + run: tox -e py314-test-instrumentation-elasticsearch-0 -- -ra - pypy3-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 pypy-3.9 Ubuntu + py314-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra + run: tox -e py314-test-instrumentation-elasticsearch-1 -- -ra - pypy3-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 pypy-3.9 Ubuntu + py314-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra + run: tox -e py314-test-instrumentation-elasticsearch-2 -- -ra - pypy3-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 pypy-3.9 Ubuntu + pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4647,10 +4761,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-3 -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra - pypy3-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 pypy-3.9 Ubuntu + pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4666,118 +4780,4 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-4 -- -ra - - py39-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-fastapi -- -ra - - py310-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-fastapi -- -ra - - py311-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-fastapi -- -ra - - py312-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-fastapi -- -ra - - py313-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-fastapi -- -ra - - py314-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-fastapi -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 3da71686468..d6ae260e936 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -32,8 +32,8 @@ env: jobs: - pypy3-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi pypy-3.9 Ubuntu + pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -49,10 +49,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-fastapi -- -ra + run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra - py39-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.9 Ubuntu + py39-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -68,10 +68,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-0 -- -ra + run: tox -e py39-test-instrumentation-falcon-0 -- -ra - py39-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.9 Ubuntu + py39-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -87,10 +87,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-1 -- -ra + run: tox -e py39-test-instrumentation-falcon-1 -- -ra - py39-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.9 Ubuntu + py39-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -106,10 +106,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-2 -- -ra + run: tox -e py39-test-instrumentation-falcon-2 -- -ra - py39-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.9 Ubuntu + py39-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -125,10 +125,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-3 -- -ra + run: tox -e py39-test-instrumentation-falcon-3 -- -ra - py310-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.10 Ubuntu + py310-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -144,10 +144,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-flask-0 -- -ra + run: tox -e py310-test-instrumentation-falcon-1 -- -ra - py310-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.10 Ubuntu + py310-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -163,10 +163,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-flask-1 -- -ra + run: tox -e py310-test-instrumentation-falcon-2 -- -ra - py310-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.10 Ubuntu + py310-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -182,10 +182,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-flask-2 -- -ra + run: tox -e py310-test-instrumentation-falcon-3 -- -ra - py310-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.10 Ubuntu + py310-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -201,10 +201,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-flask-3 -- -ra + run: tox -e py310-test-instrumentation-falcon-4 -- -ra - py311-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.11 Ubuntu + py311-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -220,10 +220,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-flask-0 -- -ra + run: tox -e py311-test-instrumentation-falcon-1 -- -ra - py311-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.11 Ubuntu + py311-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -239,10 +239,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-flask-1 -- -ra + run: tox -e py311-test-instrumentation-falcon-2 -- -ra - py311-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.11 Ubuntu + py311-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -258,10 +258,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-flask-2 -- -ra + run: tox -e py311-test-instrumentation-falcon-3 -- -ra - py311-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.11 Ubuntu + py311-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -277,10 +277,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-flask-3 -- -ra + run: tox -e py311-test-instrumentation-falcon-4 -- -ra - py312-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.12 Ubuntu + py312-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -296,10 +296,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-flask-0 -- -ra + run: tox -e py312-test-instrumentation-falcon-1 -- -ra - py312-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.12 Ubuntu + py312-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -315,10 +315,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-flask-1 -- -ra + run: tox -e py312-test-instrumentation-falcon-2 -- -ra - py312-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.12 Ubuntu + py312-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -334,10 +334,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-flask-2 -- -ra + run: tox -e py312-test-instrumentation-falcon-3 -- -ra - py312-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.12 Ubuntu + py312-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -353,10 +353,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-flask-3 -- -ra + run: tox -e py312-test-instrumentation-falcon-4 -- -ra - py313-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.13 Ubuntu + py313-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -372,314 +372,314 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-flask-0 -- -ra + run: tox -e py313-test-instrumentation-falcon-4 -- -ra - py313-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.13 Ubuntu + py314-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-flask-1 -- -ra + run: tox -e py314-test-instrumentation-falcon-4 -- -ra - py313-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.13 Ubuntu + pypy3-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-flask-2 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra - py313-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.13 Ubuntu + pypy3-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-flask-3 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra - py314-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.14 Ubuntu + pypy3-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-flask-0 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra - py314-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.14 Ubuntu + pypy3-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-flask-1 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-3 -- -ra - py314-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.14 Ubuntu + pypy3-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-flask-2 -- -ra + run: tox -e pypy3-test-instrumentation-falcon-4 -- -ra - py314-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.14 Ubuntu + py39-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-flask-3 -- -ra + run: tox -e py39-test-instrumentation-fastapi -- -ra - pypy3-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 pypy-3.9 Ubuntu + py310-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-flask-0 -- -ra + run: tox -e py310-test-instrumentation-fastapi -- -ra - pypy3-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 pypy-3.9 Ubuntu + py311-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-flask-1 -- -ra + run: tox -e py311-test-instrumentation-fastapi -- -ra - py39-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.9 Ubuntu + py312-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib -- -ra + run: tox -e py312-test-instrumentation-fastapi -- -ra - py310-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.10 Ubuntu + py313-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-urllib -- -ra + run: tox -e py313-test-instrumentation-fastapi -- -ra - py311-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.11 Ubuntu + py314-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-urllib -- -ra + run: tox -e py314-test-instrumentation-fastapi -- -ra - py312-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.12 Ubuntu + pypy3-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-urllib -- -ra + run: tox -e pypy3-test-instrumentation-fastapi -- -ra - py313-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.13 Ubuntu + py39-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-urllib -- -ra + run: tox -e py39-test-instrumentation-flask-0 -- -ra - py314-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.14 Ubuntu + py39-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-urllib -- -ra + run: tox -e py39-test-instrumentation-flask-1 -- -ra - pypy3-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib pypy-3.9 Ubuntu + py39-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib -- -ra + run: tox -e py39-test-instrumentation-flask-2 -- -ra - py39-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.9 Ubuntu + py39-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -695,29 +695,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + run: tox -e py39-test-instrumentation-flask-3 -- -ra - py39-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.9 Ubuntu + py310-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + run: tox -e py310-test-instrumentation-flask-0 -- -ra - py310-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.10 Ubuntu + py310-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -733,10 +733,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-0 -- -ra + run: tox -e py310-test-instrumentation-flask-1 -- -ra - py310-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.10 Ubuntu + py310-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -752,29 +752,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-1 -- -ra + run: tox -e py310-test-instrumentation-flask-2 -- -ra - py311-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.11 Ubuntu + py310-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-0 -- -ra + run: tox -e py310-test-instrumentation-flask-3 -- -ra - py311-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.11 Ubuntu + py311-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -790,200 +790,200 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-1 -- -ra + run: tox -e py311-test-instrumentation-flask-0 -- -ra - py312-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.12 Ubuntu + py311-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-urllib3-0 -- -ra + run: tox -e py311-test-instrumentation-flask-1 -- -ra - py312-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.12 Ubuntu + py311-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-urllib3-1 -- -ra + run: tox -e py311-test-instrumentation-flask-2 -- -ra - py313-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.13 Ubuntu + py311-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-urllib3-0 -- -ra + run: tox -e py311-test-instrumentation-flask-3 -- -ra - py313-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.13 Ubuntu + py312-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-urllib3-1 -- -ra + run: tox -e py312-test-instrumentation-flask-0 -- -ra - pypy3-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 pypy-3.9 Ubuntu + py312-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra + run: tox -e py312-test-instrumentation-flask-1 -- -ra - pypy3-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 pypy-3.9 Ubuntu + py312-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra + run: tox -e py312-test-instrumentation-flask-2 -- -ra - py39-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.9 Ubuntu + py312-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-requests -- -ra + run: tox -e py312-test-instrumentation-flask-3 -- -ra - py310-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.10 Ubuntu + py313-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-requests -- -ra + run: tox -e py313-test-instrumentation-flask-0 -- -ra - py311-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.11 Ubuntu + py313-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-requests -- -ra + run: tox -e py313-test-instrumentation-flask-1 -- -ra - py312-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.12 Ubuntu + py313-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-requests -- -ra + run: tox -e py313-test-instrumentation-flask-2 -- -ra - py313-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.13 Ubuntu + py313-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -999,10 +999,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-requests -- -ra + run: tox -e py313-test-instrumentation-flask-3 -- -ra - py314-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.14 Ubuntu + py314-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1018,181 +1018,181 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-requests -- -ra + run: tox -e py314-test-instrumentation-flask-0 -- -ra - py39-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.9 Ubuntu + py314-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-starlette-oldest -- -ra + run: tox -e py314-test-instrumentation-flask-1 -- -ra - py39-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.9 Ubuntu + py314-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-starlette-latest -- -ra + run: tox -e py314-test-instrumentation-flask-2 -- -ra - py310-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.10 Ubuntu + py314-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-starlette-oldest -- -ra + run: tox -e py314-test-instrumentation-flask-3 -- -ra - py310-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.10 Ubuntu + pypy3-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-starlette-latest -- -ra + run: tox -e pypy3-test-instrumentation-flask-0 -- -ra - py311-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.11 Ubuntu + pypy3-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-starlette-oldest -- -ra + run: tox -e pypy3-test-instrumentation-flask-1 -- -ra - py311-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.11 Ubuntu + py39-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-starlette-latest -- -ra + run: tox -e py39-test-instrumentation-urllib -- -ra - py312-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.12 Ubuntu + py310-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-starlette-oldest -- -ra + run: tox -e py310-test-instrumentation-urllib -- -ra - py312-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.12 Ubuntu + py311-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-starlette-latest -- -ra + run: tox -e py311-test-instrumentation-urllib -- -ra - py313-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.13 Ubuntu + py312-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-starlette-oldest -- -ra + run: tox -e py312-test-instrumentation-urllib -- -ra - py313-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.13 Ubuntu + py313-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1208,10 +1208,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-starlette-latest -- -ra + run: tox -e py313-test-instrumentation-urllib -- -ra - py314-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.14 Ubuntu + py314-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1227,86 +1227,86 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-starlette-oldest -- -ra + run: tox -e py314-test-instrumentation-urllib -- -ra - py314-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.14 Ubuntu + pypy3-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-starlette-latest -- -ra + run: tox -e pypy3-test-instrumentation-urllib -- -ra - pypy3-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest pypy-3.9 Ubuntu + py39-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-starlette-oldest -- -ra + run: tox -e py39-test-instrumentation-urllib3-0 -- -ra - pypy3-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest pypy-3.9 Ubuntu + py39-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-starlette-latest -- -ra + run: tox -e py39-test-instrumentation-urllib3-1 -- -ra - py39-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.9 Ubuntu + py310-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-jinja2 -- -ra + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - py310-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.10 Ubuntu + py310-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1322,10 +1322,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-jinja2 -- -ra + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - py311-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.11 Ubuntu + py311-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1341,428 +1341,428 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-jinja2 -- -ra + run: tox -e py311-test-instrumentation-urllib3-0 -- -ra - py312-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.12 Ubuntu + py311-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-jinja2 -- -ra + run: tox -e py311-test-instrumentation-urllib3-1 -- -ra - py313-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.13 Ubuntu + py312-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-jinja2 -- -ra + run: tox -e py312-test-instrumentation-urllib3-0 -- -ra - py314-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.14 Ubuntu + py312-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-jinja2 -- -ra + run: tox -e py312-test-instrumentation-urllib3-1 -- -ra - pypy3-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 pypy-3.9 Ubuntu + py313-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-jinja2 -- -ra + run: tox -e py313-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.9 Ubuntu + py313-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-logging -- -ra + run: tox -e py313-test-instrumentation-urllib3-1 -- -ra - py310-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.10 Ubuntu + pypy3-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-logging -- -ra + run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra - py311-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.11 Ubuntu + pypy3-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-logging -- -ra + run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra - py312-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.12 Ubuntu + py39-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-logging -- -ra + run: tox -e py39-test-instrumentation-requests -- -ra - py313-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.13 Ubuntu + py310-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-logging -- -ra + run: tox -e py310-test-instrumentation-requests -- -ra - py314-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.14 Ubuntu + py311-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-logging -- -ra + run: tox -e py311-test-instrumentation-requests -- -ra - pypy3-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging pypy-3.9 Ubuntu + py312-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-logging -- -ra + run: tox -e py312-test-instrumentation-requests -- -ra - py39-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.9 Ubuntu + py313-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-richconsole -- -ra + run: tox -e py313-test-instrumentation-requests -- -ra - py310-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.10 Ubuntu + py314-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-exporter-richconsole -- -ra + run: tox -e py314-test-instrumentation-requests -- -ra - py311-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.11 Ubuntu + py39-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-exporter-richconsole -- -ra + run: tox -e py39-test-instrumentation-starlette-oldest -- -ra - py312-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.12 Ubuntu + py39-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-exporter-richconsole -- -ra + run: tox -e py39-test-instrumentation-starlette-latest -- -ra - py313-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.13 Ubuntu + py310-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-exporter-richconsole -- -ra + run: tox -e py310-test-instrumentation-starlette-oldest -- -ra - py314-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.14 Ubuntu + py310-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-exporter-richconsole -- -ra + run: tox -e py310-test-instrumentation-starlette-latest -- -ra - pypy3-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole pypy-3.9 Ubuntu + py311-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-exporter-richconsole -- -ra + run: tox -e py311-test-instrumentation-starlette-oldest -- -ra - py39-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.9 Ubuntu + py311-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-prometheus-remote-write -- -ra + run: tox -e py311-test-instrumentation-starlette-latest -- -ra - py310-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.10 Ubuntu + py312-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-exporter-prometheus-remote-write -- -ra + run: tox -e py312-test-instrumentation-starlette-oldest -- -ra - py311-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.11 Ubuntu + py312-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-exporter-prometheus-remote-write -- -ra + run: tox -e py312-test-instrumentation-starlette-latest -- -ra - py312-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.12 Ubuntu + py313-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-exporter-prometheus-remote-write -- -ra + run: tox -e py313-test-instrumentation-starlette-oldest -- -ra - py313-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.13 Ubuntu + py313-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1778,10 +1778,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-exporter-prometheus-remote-write -- -ra + run: tox -e py313-test-instrumentation-starlette-latest -- -ra - py314-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.14 Ubuntu + py314-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1797,86 +1797,86 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-exporter-prometheus-remote-write -- -ra + run: tox -e py314-test-instrumentation-starlette-oldest -- -ra - pypy310-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write pypy-3.10 Ubuntu + py314-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.10 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.10" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy310-test-exporter-prometheus-remote-write -- -ra + run: tox -e py314-test-instrumentation-starlette-latest -- -ra - py39-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.9 Ubuntu + pypy3-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysql-0 -- -ra + run: tox -e pypy3-test-instrumentation-starlette-oldest -- -ra - py39-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.9 Ubuntu + pypy3-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra + run: tox -e pypy3-test-instrumentation-starlette-latest -- -ra - py310-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.10 Ubuntu + py39-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-mysql-0 -- -ra + run: tox -e py39-test-instrumentation-jinja2 -- -ra - py310-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.10 Ubuntu + py310-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1892,10 +1892,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-mysql-1 -- -ra + run: tox -e py310-test-instrumentation-jinja2 -- -ra - py311-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.11 Ubuntu + py311-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1911,162 +1911,200 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-mysql-0 -- -ra + run: tox -e py311-test-instrumentation-jinja2 -- -ra - py311-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.11 Ubuntu + py312-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-mysql-1 -- -ra + run: tox -e py312-test-instrumentation-jinja2 -- -ra - py312-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.12 Ubuntu + py313-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-mysql-0 -- -ra + run: tox -e py313-test-instrumentation-jinja2 -- -ra - py312-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.12 Ubuntu + py314-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-mysql-1 -- -ra + run: tox -e py314-test-instrumentation-jinja2 -- -ra - py313-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.13 Ubuntu + pypy3-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-mysql-0 -- -ra + run: tox -e pypy3-test-instrumentation-jinja2 -- -ra - py313-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.13 Ubuntu + py39-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-mysql-1 -- -ra + run: tox -e py39-test-instrumentation-logging -- -ra - py314-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.14 Ubuntu + py310-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-mysql-0 -- -ra + run: tox -e py310-test-instrumentation-logging -- -ra - py314-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.14 Ubuntu + py311-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-mysql-1 -- -ra + run: tox -e py311-test-instrumentation-logging -- -ra - pypy3-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 pypy-3.9 Ubuntu + py312-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra + run: tox -e py312-test-instrumentation-logging -- -ra - pypy3-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 pypy-3.9 Ubuntu + py313-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-logging -- -ra + + py314-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-logging -- -ra + + pypy3-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2082,10 +2120,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra + run: tox -e pypy3-test-instrumentation-logging -- -ra - py39-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.9 Ubuntu + py39-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2101,10 +2139,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra + run: tox -e py39-test-exporter-richconsole -- -ra - py310-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.10 Ubuntu + py310-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2120,10 +2158,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-mysqlclient -- -ra + run: tox -e py310-test-exporter-richconsole -- -ra - py311-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.11 Ubuntu + py311-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2139,10 +2177,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-mysqlclient -- -ra + run: tox -e py311-test-exporter-richconsole -- -ra - py312-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.12 Ubuntu + py312-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2158,10 +2196,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-mysqlclient -- -ra + run: tox -e py312-test-exporter-richconsole -- -ra - py313-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.13 Ubuntu + py313-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2177,10 +2215,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-mysqlclient -- -ra + run: tox -e py313-test-exporter-richconsole -- -ra - py314-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.14 Ubuntu + py314-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2196,10 +2234,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-mysqlclient -- -ra + run: tox -e py314-test-exporter-richconsole -- -ra - pypy3-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient pypy-3.9 Ubuntu + pypy3-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2215,10 +2253,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra + run: tox -e pypy3-test-exporter-richconsole -- -ra - py39-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.9 Ubuntu + py39-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2234,10 +2272,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra + run: tox -e py39-test-exporter-prometheus-remote-write -- -ra - py310-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.10 Ubuntu + py310-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2253,10 +2291,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-psycopg2 -- -ra + run: tox -e py310-test-exporter-prometheus-remote-write -- -ra - py311-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.11 Ubuntu + py311-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2272,10 +2310,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-psycopg2 -- -ra + run: tox -e py311-test-exporter-prometheus-remote-write -- -ra - py312-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.12 Ubuntu + py312-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2291,10 +2329,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-psycopg2 -- -ra + run: tox -e py312-test-exporter-prometheus-remote-write -- -ra - py313-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.13 Ubuntu + py313-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2310,10 +2348,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-psycopg2 -- -ra + run: tox -e py313-test-exporter-prometheus-remote-write -- -ra - py314-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.14 Ubuntu + py314-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2329,200 +2367,200 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-psycopg2 -- -ra + run: tox -e py314-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.9 Ubuntu + pypy310-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra + run: tox -e pypy310-test-exporter-prometheus-remote-write -- -ra - py310-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.10 Ubuntu + py39-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-psycopg2-binary -- -ra + run: tox -e py39-test-instrumentation-mysql-0 -- -ra - py311-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.11 Ubuntu + py39-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-psycopg2-binary -- -ra + run: tox -e py39-test-instrumentation-mysql-1 -- -ra - py312-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.12 Ubuntu + py310-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-psycopg2-binary -- -ra + run: tox -e py310-test-instrumentation-mysql-0 -- -ra - py313-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.13 Ubuntu + py310-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-psycopg2-binary -- -ra + run: tox -e py310-test-instrumentation-mysql-1 -- -ra - py314-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.14 Ubuntu + py311-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-psycopg2-binary -- -ra + run: tox -e py311-test-instrumentation-mysql-0 -- -ra - py39-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.9 Ubuntu + py311-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra + run: tox -e py311-test-instrumentation-mysql-1 -- -ra - py310-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.10 Ubuntu + py312-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-psycopg -- -ra + run: tox -e py312-test-instrumentation-mysql-0 -- -ra - py311-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.11 Ubuntu + py312-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-psycopg -- -ra + run: tox -e py312-test-instrumentation-mysql-1 -- -ra - py312-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.12 Ubuntu + py313-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-psycopg -- -ra + run: tox -e py313-test-instrumentation-mysql-0 -- -ra - py313-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.13 Ubuntu + py313-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2538,10 +2576,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-psycopg -- -ra + run: tox -e py313-test-instrumentation-mysql-1 -- -ra - py314-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.14 Ubuntu + py314-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2557,10 +2595,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-psycopg -- -ra + run: tox -e py314-test-instrumentation-mysql-0 -- -ra - pypy3-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg pypy-3.9 Ubuntu + py314-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-mysql-1 -- -ra + + pypy3-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2576,29 +2633,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-psycopg -- -ra + run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra - py39-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.9 Ubuntu + pypy3-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra - py39-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.9 Ubuntu + py39-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2614,143 +2671,143 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py39-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.9 Ubuntu + py310-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py310-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.9 Ubuntu + py311-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py311-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.9 Ubuntu + py312-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py312-test-instrumentation-mysqlclient -- -ra - py310-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.10 Ubuntu + py313-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py313-test-instrumentation-mysqlclient -- -ra - py310-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.10 Ubuntu + py314-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py314-test-instrumentation-mysqlclient -- -ra - py310-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.10 Ubuntu + pypy3-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra + run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra - py310-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.10 Ubuntu + py39-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py39-test-instrumentation-psycopg2 -- -ra - py310-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.10 Ubuntu + py310-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2766,10 +2823,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py310-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.11 Ubuntu + py311-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2785,124 +2842,124 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py311-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.11 Ubuntu + py312-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py312-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.11 Ubuntu + py313-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py313-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.11 Ubuntu + py314-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py314-test-instrumentation-psycopg2 -- -ra - py311-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.11 Ubuntu + py39-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra - py312-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.12 Ubuntu + py310-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-psycopg2-binary -- -ra - py312-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.12 Ubuntu + py311-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py311-test-instrumentation-psycopg2-binary -- -ra - py312-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.12 Ubuntu + py312-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2918,124 +2975,124 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py312-test-instrumentation-psycopg2-binary -- -ra - py312-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.12 Ubuntu + py313-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py313-test-instrumentation-psycopg2-binary -- -ra - py312-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.12 Ubuntu + py314-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py314-test-instrumentation-psycopg2-binary -- -ra - py313-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.13 Ubuntu + py39-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py39-test-instrumentation-psycopg -- -ra - py313-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.13 Ubuntu + py310-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py310-test-instrumentation-psycopg -- -ra - py313-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.13 Ubuntu + py311-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py311-test-instrumentation-psycopg -- -ra - py313-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.13 Ubuntu + py312-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py312-test-instrumentation-psycopg -- -ra - py313-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.13 Ubuntu + py313-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3051,10 +3108,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py313-test-instrumentation-psycopg -- -ra - py314-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.14 Ubuntu + py314-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3070,200 +3127,200 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py314-test-instrumentation-psycopg -- -ra - py314-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.14 Ubuntu + pypy3-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-1 -- -ra + run: tox -e pypy3-test-instrumentation-psycopg -- -ra - py314-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.14 Ubuntu + py39-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra - py314-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.14 Ubuntu + py39-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra - py314-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.14 Ubuntu + py39-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra - pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 pypy-3.9 Ubuntu + py39-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra - pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 pypy-3.9 Ubuntu + py39-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra - pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 pypy-3.9 Ubuntu + py310-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 pypy-3.9 Ubuntu + py310-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 pypy-3.9 Ubuntu + py310-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra - py39-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.9 Ubuntu + py310-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymongo -- -ra + run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra - py310-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.10 Ubuntu + py310-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3279,10 +3336,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pymongo -- -ra + run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra - py311-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.11 Ubuntu + py311-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3298,143 +3355,143 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pymongo -- -ra + run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra - py312-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.12 Ubuntu + py311-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pymongo -- -ra + run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra - py313-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.13 Ubuntu + py311-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pymongo -- -ra + run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra - py314-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.14 Ubuntu + py311-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pymongo -- -ra + run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra - pypy3-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo pypy-3.9 Ubuntu + py311-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-pymongo -- -ra + run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra - py39-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.9 Ubuntu + py312-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymysql -- -ra + run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra - py310-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.10 Ubuntu + py312-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pymysql -- -ra + run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra - py311-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.11 Ubuntu + py312-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pymysql -- -ra + run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra - py312-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.12 Ubuntu + py312-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3450,162 +3507,162 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pymysql -- -ra + run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra - py313-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.13 Ubuntu + py312-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pymysql -- -ra + run: tox -e py312-test-instrumentation-pymemcache-4 -- -ra - py314-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.14 Ubuntu + py313-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pymysql -- -ra + run: tox -e py313-test-instrumentation-pymemcache-0 -- -ra - pypy3-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql pypy-3.9 Ubuntu + py313-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-pymysql -- -ra + run: tox -e py313-test-instrumentation-pymemcache-1 -- -ra - py39-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.9 Ubuntu + py313-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymssql -- -ra + run: tox -e py313-test-instrumentation-pymemcache-2 -- -ra - py310-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.10 Ubuntu + py313-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pymssql -- -ra + run: tox -e py313-test-instrumentation-pymemcache-3 -- -ra - py311-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.11 Ubuntu + py313-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pymssql -- -ra + run: tox -e py313-test-instrumentation-pymemcache-4 -- -ra - py312-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.12 Ubuntu + py314-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pymssql -- -ra + run: tox -e py314-test-instrumentation-pymemcache-0 -- -ra - py313-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.13 Ubuntu + py314-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pymssql -- -ra + run: tox -e py314-test-instrumentation-pymemcache-1 -- -ra - py314-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.14 Ubuntu + py314-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3621,124 +3678,124 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pymssql -- -ra + run: tox -e py314-test-instrumentation-pymemcache-2 -- -ra - py39-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.9 Ubuntu + py314-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pyramid -- -ra + run: tox -e py314-test-instrumentation-pymemcache-3 -- -ra - py310-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.10 Ubuntu + py314-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-pyramid -- -ra + run: tox -e py314-test-instrumentation-pymemcache-4 -- -ra - py311-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.11 Ubuntu + pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-pyramid -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra - py312-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.12 Ubuntu + pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-pyramid -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra - py313-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.13 Ubuntu + pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-pyramid -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra - py314-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.14 Ubuntu + pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-pyramid -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra - pypy3-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid pypy-3.9 Ubuntu + pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3754,10 +3811,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-pyramid -- -ra + run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra - py39-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.9 Ubuntu + py39-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3773,10 +3830,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asgi -- -ra + run: tox -e py39-test-instrumentation-pymongo -- -ra - py310-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.10 Ubuntu + py310-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3792,10 +3849,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-asgi -- -ra + run: tox -e py310-test-instrumentation-pymongo -- -ra - py311-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.11 Ubuntu + py311-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3811,10 +3868,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-asgi -- -ra + run: tox -e py311-test-instrumentation-pymongo -- -ra - py312-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.12 Ubuntu + py312-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3830,10 +3887,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-asgi -- -ra + run: tox -e py312-test-instrumentation-pymongo -- -ra - py313-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.13 Ubuntu + py313-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3849,10 +3906,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-asgi -- -ra + run: tox -e py313-test-instrumentation-pymongo -- -ra - py314-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.14 Ubuntu + py314-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3868,10 +3925,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-asgi -- -ra + run: tox -e py314-test-instrumentation-pymongo -- -ra - pypy3-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi pypy-3.9 Ubuntu + pypy3-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3887,10 +3944,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-asgi -- -ra + run: tox -e pypy3-test-instrumentation-pymongo -- -ra - py39-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.9 Ubuntu + py39-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3906,10 +3963,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg -- -ra + run: tox -e py39-test-instrumentation-pymysql -- -ra - py310-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.10 Ubuntu + py310-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3925,10 +3982,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-asyncpg -- -ra + run: tox -e py310-test-instrumentation-pymysql -- -ra - py311-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.11 Ubuntu + py311-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3944,10 +4001,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-asyncpg -- -ra + run: tox -e py311-test-instrumentation-pymysql -- -ra - py312-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.12 Ubuntu + py312-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3963,10 +4020,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-asyncpg -- -ra + run: tox -e py312-test-instrumentation-pymysql -- -ra - py313-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.13 Ubuntu + py313-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3982,10 +4039,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-asyncpg -- -ra + run: tox -e py313-test-instrumentation-pymysql -- -ra - py314-test-instrumentation-asyncpg_ubuntu-latest: - name: instrumentation-asyncpg 3.14 Ubuntu + py314-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4001,143 +4058,143 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-asyncpg -- -ra + run: tox -e py314-test-instrumentation-pymysql -- -ra - py39-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.9 Ubuntu + pypy3-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlite3 -- -ra + run: tox -e pypy3-test-instrumentation-pymysql -- -ra - py310-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.10 Ubuntu + py39-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-sqlite3 -- -ra + run: tox -e py39-test-instrumentation-pymssql -- -ra - py311-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.11 Ubuntu + py310-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-sqlite3 -- -ra + run: tox -e py310-test-instrumentation-pymssql -- -ra - py312-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.12 Ubuntu + py311-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-sqlite3 -- -ra + run: tox -e py311-test-instrumentation-pymssql -- -ra - py313-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.13 Ubuntu + py312-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-sqlite3 -- -ra + run: tox -e py312-test-instrumentation-pymssql -- -ra - py314-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.14 Ubuntu + py313-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-sqlite3 -- -ra + run: tox -e py313-test-instrumentation-pymssql -- -ra - pypy3-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 pypy-3.9 Ubuntu + py314-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra + run: tox -e py314-test-instrumentation-pymssql -- -ra - py39-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.9 Ubuntu + py39-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4153,10 +4210,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra + run: tox -e py39-test-instrumentation-pyramid -- -ra - py310-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.10 Ubuntu + py310-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4172,10 +4229,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-wsgi -- -ra + run: tox -e py310-test-instrumentation-pyramid -- -ra - py311-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.11 Ubuntu + py311-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4191,10 +4248,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-wsgi -- -ra + run: tox -e py311-test-instrumentation-pyramid -- -ra - py312-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.12 Ubuntu + py312-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4210,10 +4267,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-wsgi -- -ra + run: tox -e py312-test-instrumentation-pyramid -- -ra - py313-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.13 Ubuntu + py313-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4229,10 +4286,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-wsgi -- -ra + run: tox -e py313-test-instrumentation-pyramid -- -ra - py314-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.14 Ubuntu + py314-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4248,10 +4305,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-wsgi -- -ra + run: tox -e py314-test-instrumentation-pyramid -- -ra - pypy3-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi pypy-3.9 Ubuntu + pypy3-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4267,29 +4324,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-wsgi -- -ra - - py39-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0 -- -ra + run: tox -e pypy3-test-instrumentation-pyramid -- -ra - py39-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.9 Ubuntu + py39-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4305,29 +4343,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1 -- -ra - - py310-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-0 -- -ra + run: tox -e py39-test-instrumentation-asgi -- -ra - py310-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.10 Ubuntu + py310-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4343,29 +4362,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-grpc-1 -- -ra - - py311-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-grpc-0 -- -ra + run: tox -e py310-test-instrumentation-asgi -- -ra - py311-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.11 Ubuntu + py311-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4381,10 +4381,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-grpc-1 -- -ra + run: tox -e py311-test-instrumentation-asgi -- -ra - py312-test-instrumentation-grpc-0_ubuntu-latest: - name: instrumentation-grpc-0 3.12 Ubuntu + py312-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4400,67 +4400,67 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-grpc-0 -- -ra + run: tox -e py312-test-instrumentation-asgi -- -ra - py312-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.12 Ubuntu + py313-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-grpc-1 -- -ra + run: tox -e py313-test-instrumentation-asgi -- -ra - py313-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.13 Ubuntu + py314-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-grpc-1 -- -ra + run: tox -e py314-test-instrumentation-asgi -- -ra - py314-test-instrumentation-grpc-1_ubuntu-latest: - name: instrumentation-grpc-1 3.14 Ubuntu + pypy3-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-grpc-1 -- -ra + run: tox -e pypy3-test-instrumentation-asgi -- -ra - py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.9 Ubuntu + py39-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4476,10 +4476,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py39-test-instrumentation-asyncpg-wrapt1 -- -ra - py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.9 Ubuntu + py39-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4495,10 +4495,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py39-test-instrumentation-asyncpg-wrapt2 -- -ra - py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.10 Ubuntu + py310-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4514,10 +4514,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py310-test-instrumentation-asyncpg-wrapt1 -- -ra - py310-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.10 Ubuntu + py310-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4533,10 +4533,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py310-test-instrumentation-asyncpg-wrapt2 -- -ra - py311-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.11 Ubuntu + py311-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4552,10 +4552,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py311-test-instrumentation-asyncpg-wrapt1 -- -ra - py311-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.11 Ubuntu + py311-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4571,10 +4571,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py311-test-instrumentation-asyncpg-wrapt2 -- -ra - py312-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.12 Ubuntu + py312-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4590,10 +4590,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py312-test-instrumentation-asyncpg-wrapt1 -- -ra - py312-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.12 Ubuntu + py312-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4609,10 +4609,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py312-test-instrumentation-asyncpg-wrapt2 -- -ra - py313-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.13 Ubuntu + py313-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4628,10 +4628,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py313-test-instrumentation-asyncpg-wrapt1 -- -ra - py313-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.13 Ubuntu + py313-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4647,10 +4647,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py313-test-instrumentation-asyncpg-wrapt2 -- -ra - py314-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.14 Ubuntu + py314-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -4666,118 +4666,118 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py314-test-instrumentation-asyncpg-wrapt1 -- -ra - pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: - name: instrumentation-sqlalchemy-0 pypy-3.9 Ubuntu + py314-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra + run: tox -e py314-test-instrumentation-asyncpg-wrapt2 -- -ra - pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 pypy-3.9 Ubuntu + py39-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py39-test-instrumentation-sqlite3 -- -ra - pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 pypy-3.9 Ubuntu + py310-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py310-test-instrumentation-sqlite3 -- -ra - py39-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.9 Ubuntu + py311-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-redis -- -ra + run: tox -e py311-test-instrumentation-sqlite3 -- -ra - py310-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.10 Ubuntu + py312-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-redis -- -ra + run: tox -e py312-test-instrumentation-sqlite3 -- -ra - py311-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.11 Ubuntu + py313-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-redis -- -ra + run: tox -e py313-test-instrumentation-sqlite3 -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index afa723c45a2..84909806377 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -32,46 +32,8 @@ env: jobs: - py312-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-redis -- -ra - - py313-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-redis -- -ra - - py314-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.14 Ubuntu + py314-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -87,10 +49,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-redis -- -ra + run: tox -e py314-test-instrumentation-sqlite3 -- -ra - pypy3-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis pypy-3.9 Ubuntu + pypy3-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -106,10 +68,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-redis -- -ra + run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra - py39-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.9 Ubuntu + py39-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -125,10 +87,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-remoulade -- -ra + run: tox -e py39-test-instrumentation-wsgi -- -ra - py310-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.10 Ubuntu + py310-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -144,10 +106,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-remoulade -- -ra + run: tox -e py310-test-instrumentation-wsgi -- -ra - py311-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.11 Ubuntu + py311-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -163,10 +125,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-remoulade -- -ra + run: tox -e py311-test-instrumentation-wsgi -- -ra - py312-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.12 Ubuntu + py312-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -182,10 +144,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-remoulade -- -ra + run: tox -e py312-test-instrumentation-wsgi -- -ra - py313-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.13 Ubuntu + py313-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -201,10 +163,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-remoulade -- -ra + run: tox -e py313-test-instrumentation-wsgi -- -ra - py314-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.14 Ubuntu + py314-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -220,162 +182,162 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-remoulade -- -ra + run: tox -e py314-test-instrumentation-wsgi -- -ra - py39-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.9 Ubuntu + pypy3-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-celery -- -ra + run: tox -e pypy3-test-instrumentation-wsgi -- -ra - py310-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.10 Ubuntu + py39-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-celery -- -ra + run: tox -e py39-test-instrumentation-grpc-0-wrapt1 -- -ra - py311-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.11 Ubuntu + py39-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-celery -- -ra + run: tox -e py39-test-instrumentation-grpc-0-wrapt2 -- -ra - py312-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.12 Ubuntu + py39-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-celery -- -ra + run: tox -e py39-test-instrumentation-grpc-1-wrapt1 -- -ra - py313-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.13 Ubuntu + py39-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-celery -- -ra + run: tox -e py39-test-instrumentation-grpc-1-wrapt2 -- -ra - py314-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.14 Ubuntu + py310-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-celery -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra - pypy3-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery pypy-3.9 Ubuntu + py310-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-celery -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra - py39-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.9 Ubuntu + py310-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-system-metrics -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra - py310-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.10 Ubuntu + py310-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -391,10 +353,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-system-metrics -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra - py311-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.11 Ubuntu + py311-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -410,162 +372,162 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-system-metrics -- -ra + run: tox -e py311-test-instrumentation-grpc-0-wrapt1 -- -ra - py312-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.12 Ubuntu + py311-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-system-metrics -- -ra + run: tox -e py311-test-instrumentation-grpc-0-wrapt2 -- -ra - py313-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.13 Ubuntu + py311-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-system-metrics -- -ra + run: tox -e py311-test-instrumentation-grpc-1-wrapt1 -- -ra - py314-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.14 Ubuntu + py311-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-system-metrics -- -ra + run: tox -e py311-test-instrumentation-grpc-1-wrapt2 -- -ra - pypy3-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics pypy-3.9 Ubuntu + py312-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-system-metrics -- -ra + run: tox -e py312-test-instrumentation-grpc-0-wrapt1 -- -ra - py39-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.9 Ubuntu + py312-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-threading -- -ra + run: tox -e py312-test-instrumentation-grpc-0-wrapt2 -- -ra - py310-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.10 Ubuntu + py312-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-threading -- -ra + run: tox -e py312-test-instrumentation-grpc-1-wrapt1 -- -ra - py311-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.11 Ubuntu + py312-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-threading -- -ra + run: tox -e py312-test-instrumentation-grpc-1-wrapt2 -- -ra - py312-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.12 Ubuntu + py313-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-threading -- -ra + run: tox -e py313-test-instrumentation-grpc-1-wrapt1 -- -ra - py313-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.13 Ubuntu + py313-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -581,10 +543,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-threading -- -ra + run: tox -e py313-test-instrumentation-grpc-1-wrapt2 -- -ra - py314-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.14 Ubuntu + py314-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -600,29 +562,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-threading -- -ra + run: tox -e py314-test-instrumentation-grpc-1-wrapt1 -- -ra - pypy3-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading pypy-3.9 Ubuntu + py314-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-threading -- -ra + run: tox -e py314-test-instrumentation-grpc-1-wrapt2 -- -ra - py39-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.9 Ubuntu + py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -638,238 +600,238 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-tornado -- -ra + run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra - py310-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.10 Ubuntu + py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-tornado -- -ra + run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra - py311-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.11 Ubuntu + py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-tornado -- -ra + run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra - py312-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.12 Ubuntu + py310-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-tornado -- -ra + run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra - py313-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.13 Ubuntu + py311-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-tornado -- -ra + run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra - py314-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.14 Ubuntu + py311-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-tornado -- -ra + run: tox -e py311-test-instrumentation-sqlalchemy-2 -- -ra - pypy3-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado pypy-3.9 Ubuntu + py312-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-tornado -- -ra + run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra - py39-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.9 Ubuntu + py312-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-tortoiseorm -- -ra + run: tox -e py312-test-instrumentation-sqlalchemy-2 -- -ra - py310-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.10 Ubuntu + py313-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-tortoiseorm -- -ra + run: tox -e py313-test-instrumentation-sqlalchemy-1 -- -ra - py311-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.11 Ubuntu + py313-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-tortoiseorm -- -ra + run: tox -e py313-test-instrumentation-sqlalchemy-2 -- -ra - py312-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.12 Ubuntu + py314-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-tortoiseorm -- -ra + run: tox -e py314-test-instrumentation-sqlalchemy-2 -- -ra - py313-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.13 Ubuntu + pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: + name: instrumentation-sqlalchemy-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-tortoiseorm -- -ra + run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra - py314-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.14 Ubuntu + pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-tortoiseorm -- -ra + run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra - pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm pypy-3.9 Ubuntu + pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -885,10 +847,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra + run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra - py39-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.9 Ubuntu + py39-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -904,219 +866,238 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0 -- -ra + run: tox -e py39-test-instrumentation-redis -- -ra - py39-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.9 Ubuntu + py310-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1 -- -ra + run: tox -e py310-test-instrumentation-redis -- -ra - py310-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.10 Ubuntu + py311-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-httpx-0 -- -ra + run: tox -e py311-test-instrumentation-redis -- -ra - py310-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.10 Ubuntu + py312-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-httpx-1 -- -ra + run: tox -e py312-test-instrumentation-redis -- -ra - py311-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.11 Ubuntu + py313-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-httpx-0 -- -ra + run: tox -e py313-test-instrumentation-redis -- -ra - py311-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.11 Ubuntu + py314-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-httpx-1 -- -ra + run: tox -e py314-test-instrumentation-redis -- -ra - py312-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 3.12 Ubuntu + pypy3-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-redis -- -ra + + py39-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-httpx-0 -- -ra + run: tox -e py39-test-instrumentation-remoulade -- -ra - py312-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.12 Ubuntu + py310-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-httpx-1 -- -ra + run: tox -e py310-test-instrumentation-remoulade -- -ra - py313-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.13 Ubuntu + py311-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-httpx-1 -- -ra + run: tox -e py311-test-instrumentation-remoulade -- -ra - py314-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 3.14 Ubuntu + py312-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-httpx-1 -- -ra + run: tox -e py312-test-instrumentation-remoulade -- -ra - pypy3-test-instrumentation-httpx-0_ubuntu-latest: - name: instrumentation-httpx-0 pypy-3.9 Ubuntu + py313-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-httpx-0 -- -ra + run: tox -e py313-test-instrumentation-remoulade -- -ra - pypy3-test-instrumentation-httpx-1_ubuntu-latest: - name: instrumentation-httpx-1 pypy-3.9 Ubuntu + py314-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-httpx-1 -- -ra + run: tox -e py314-test-instrumentation-remoulade -- -ra - py39-test-util-http_ubuntu-latest: - name: util-http 3.9 Ubuntu + py39-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1132,10 +1113,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-util-http -- -ra + run: tox -e py39-test-instrumentation-celery -- -ra - py310-test-util-http_ubuntu-latest: - name: util-http 3.10 Ubuntu + py310-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1151,10 +1132,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-util-http -- -ra + run: tox -e py310-test-instrumentation-celery -- -ra - py311-test-util-http_ubuntu-latest: - name: util-http 3.11 Ubuntu + py311-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1170,10 +1151,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-util-http -- -ra + run: tox -e py311-test-instrumentation-celery -- -ra - py312-test-util-http_ubuntu-latest: - name: util-http 3.12 Ubuntu + py312-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1189,10 +1170,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-util-http -- -ra + run: tox -e py312-test-instrumentation-celery -- -ra - py313-test-util-http_ubuntu-latest: - name: util-http 3.13 Ubuntu + py313-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1208,10 +1189,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-util-http -- -ra + run: tox -e py313-test-instrumentation-celery -- -ra - py314-test-util-http_ubuntu-latest: - name: util-http 3.14 Ubuntu + py314-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1227,10 +1208,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-util-http -- -ra + run: tox -e py314-test-instrumentation-celery -- -ra - pypy3-test-util-http_ubuntu-latest: - name: util-http pypy-3.9 Ubuntu + pypy3-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1246,10 +1227,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-util-http -- -ra + run: tox -e pypy3-test-instrumentation-celery -- -ra - py39-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.9 Ubuntu + py39-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1265,10 +1246,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-credential-provider-gcp -- -ra + run: tox -e py39-test-instrumentation-system-metrics -- -ra - py310-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.10 Ubuntu + py310-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1284,10 +1265,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-exporter-credential-provider-gcp -- -ra + run: tox -e py310-test-instrumentation-system-metrics -- -ra - py311-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.11 Ubuntu + py311-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1303,10 +1284,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-exporter-credential-provider-gcp -- -ra + run: tox -e py311-test-instrumentation-system-metrics -- -ra - py312-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.12 Ubuntu + py312-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1322,10 +1303,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-exporter-credential-provider-gcp -- -ra + run: tox -e py312-test-instrumentation-system-metrics -- -ra - py313-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.13 Ubuntu + py313-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1341,10 +1322,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-exporter-credential-provider-gcp -- -ra + run: tox -e py313-test-instrumentation-system-metrics -- -ra - py314-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.14 Ubuntu + py314-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1360,10 +1341,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-exporter-credential-provider-gcp -- -ra + run: tox -e py314-test-instrumentation-system-metrics -- -ra - py39-test-util-genai_ubuntu-latest: - name: util-genai 3.9 Ubuntu + pypy3-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-system-metrics -- -ra + + py39-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1379,10 +1379,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-util-genai -- -ra + run: tox -e py39-test-instrumentation-threading -- -ra - py310-test-util-genai_ubuntu-latest: - name: util-genai 3.10 Ubuntu + py310-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1398,10 +1398,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-util-genai -- -ra + run: tox -e py310-test-instrumentation-threading -- -ra - py311-test-util-genai_ubuntu-latest: - name: util-genai 3.11 Ubuntu + py311-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1417,10 +1417,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-util-genai -- -ra + run: tox -e py311-test-instrumentation-threading -- -ra - py312-test-util-genai_ubuntu-latest: - name: util-genai 3.12 Ubuntu + py312-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1436,10 +1436,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-util-genai -- -ra + run: tox -e py312-test-instrumentation-threading -- -ra - py313-test-util-genai_ubuntu-latest: - name: util-genai 3.13 Ubuntu + py313-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1455,10 +1455,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-util-genai -- -ra + run: tox -e py313-test-instrumentation-threading -- -ra - py314-test-util-genai_ubuntu-latest: - name: util-genai 3.14 Ubuntu + py314-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1474,10 +1474,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-util-genai -- -ra + run: tox -e py314-test-instrumentation-threading -- -ra - pypy3-test-util-genai_ubuntu-latest: - name: util-genai pypy-3.9 Ubuntu + pypy3-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1493,10 +1493,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-util-genai -- -ra + run: tox -e pypy3-test-instrumentation-threading -- -ra - py39-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.9 Ubuntu + py39-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1512,238 +1512,238 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-aws-xray-0 -- -ra + run: tox -e py39-test-instrumentation-tornado -- -ra - py39-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.9 Ubuntu + py310-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-aws-xray-1 -- -ra + run: tox -e py310-test-instrumentation-tornado -- -ra - py310-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.10 Ubuntu + py311-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-propagator-aws-xray-0 -- -ra + run: tox -e py311-test-instrumentation-tornado -- -ra - py310-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.10 Ubuntu + py312-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-propagator-aws-xray-1 -- -ra + run: tox -e py312-test-instrumentation-tornado -- -ra - py311-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.11 Ubuntu + py313-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-propagator-aws-xray-0 -- -ra + run: tox -e py313-test-instrumentation-tornado -- -ra - py311-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.11 Ubuntu + py314-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-propagator-aws-xray-1 -- -ra + run: tox -e py314-test-instrumentation-tornado -- -ra - py312-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.12 Ubuntu + pypy3-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-propagator-aws-xray-0 -- -ra + run: tox -e pypy3-test-instrumentation-tornado -- -ra - py312-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.12 Ubuntu + py39-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-propagator-aws-xray-1 -- -ra + run: tox -e py39-test-instrumentation-tortoiseorm -- -ra - py313-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.13 Ubuntu + py310-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-propagator-aws-xray-0 -- -ra + run: tox -e py310-test-instrumentation-tortoiseorm -- -ra - py313-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.13 Ubuntu + py311-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-propagator-aws-xray-1 -- -ra + run: tox -e py311-test-instrumentation-tortoiseorm -- -ra - py314-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.14 Ubuntu + py312-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-propagator-aws-xray-0 -- -ra + run: tox -e py312-test-instrumentation-tortoiseorm -- -ra - py314-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.14 Ubuntu + py313-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-propagator-aws-xray-1 -- -ra + run: tox -e py313-test-instrumentation-tortoiseorm -- -ra - pypy3-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 pypy-3.9 Ubuntu + py314-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra + run: tox -e py314-test-instrumentation-tortoiseorm -- -ra - pypy3-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 pypy-3.9 Ubuntu + pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1759,10 +1759,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra + run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra - py39-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.9 Ubuntu + py39-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: + name: instrumentation-httpx-0-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1778,200 +1778,200 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-ot-trace -- -ra + run: tox -e py39-test-instrumentation-httpx-0-wrapt1 -- -ra - py310-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.10 Ubuntu + py39-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-propagator-ot-trace -- -ra + run: tox -e py39-test-instrumentation-httpx-0-wrapt2 -- -ra - py311-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.11 Ubuntu + py39-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-propagator-ot-trace -- -ra + run: tox -e py39-test-instrumentation-httpx-1-wrapt1 -- -ra - py312-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.12 Ubuntu + py39-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-propagator-ot-trace -- -ra + run: tox -e py39-test-instrumentation-httpx-1-wrapt2 -- -ra - py313-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.13 Ubuntu + py310-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: + name: instrumentation-httpx-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-propagator-ot-trace -- -ra + run: tox -e py310-test-instrumentation-httpx-0-wrapt1 -- -ra - py314-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.14 Ubuntu + py310-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-propagator-ot-trace -- -ra + run: tox -e py310-test-instrumentation-httpx-0-wrapt2 -- -ra - pypy3-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace pypy-3.9 Ubuntu + py310-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-propagator-ot-trace -- -ra + run: tox -e py310-test-instrumentation-httpx-1-wrapt1 -- -ra - py39-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.9 Ubuntu + py310-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py310-test-instrumentation-httpx-1-wrapt2 -- -ra - py39-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.9 Ubuntu + py311-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: + name: instrumentation-httpx-0-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py311-test-instrumentation-httpx-0-wrapt1 -- -ra - py310-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.10 Ubuntu + py311-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py311-test-instrumentation-httpx-0-wrapt2 -- -ra - py310-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.10 Ubuntu + py311-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py311-test-instrumentation-httpx-1-wrapt1 -- -ra - py311-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.11 Ubuntu + py311-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1987,29 +1987,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py311-test-instrumentation-httpx-1-wrapt2 -- -ra - py311-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.11 Ubuntu + py312-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: + name: instrumentation-httpx-0-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py312-test-instrumentation-httpx-0-wrapt1 -- -ra - py312-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.12 Ubuntu + py312-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2025,10 +2025,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py312-test-instrumentation-httpx-0-wrapt2 -- -ra - py312-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.12 Ubuntu + py312-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2044,29 +2044,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py312-test-instrumentation-httpx-1-wrapt1 -- -ra - py313-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.13 Ubuntu + py312-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py312-test-instrumentation-httpx-1-wrapt2 -- -ra - py313-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.13 Ubuntu + py313-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2082,29 +2082,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py313-test-instrumentation-httpx-1-wrapt1 -- -ra - py314-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 3.14 Ubuntu + py313-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py313-test-instrumentation-httpx-1-wrapt2 -- -ra - py314-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 3.14 Ubuntu + py314-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2120,29 +2120,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-sio-pika-1 -- -ra + run: tox -e py314-test-instrumentation-httpx-1-wrapt1 -- -ra - pypy3-test-instrumentation-sio-pika-0_ubuntu-latest: - name: instrumentation-sio-pika-0 pypy-3.9 Ubuntu + py314-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-sio-pika-0 -- -ra + run: tox -e py314-test-instrumentation-httpx-1-wrapt2 -- -ra - pypy3-test-instrumentation-sio-pika-1_ubuntu-latest: - name: instrumentation-sio-pika-1 pypy-3.9 Ubuntu + pypy3-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2158,29 +2158,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-sio-pika-1 -- -ra + run: tox -e pypy3-test-instrumentation-httpx-0-wrapt2 -- -ra - py39-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.9 Ubuntu + pypy3-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra + run: tox -e pypy3-test-instrumentation-httpx-1-wrapt2 -- -ra - py39-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.9 Ubuntu + py39-test-util-http_ubuntu-latest: + name: util-http 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2196,67 +2196,846 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py39-test-util-http -- -ra - py39-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.9 Ubuntu + py310-test-util-http_ubuntu-latest: + name: util-http 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py310-test-util-http -- -ra - py39-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.9 Ubuntu + py311-test-util-http_ubuntu-latest: + name: util-http 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py311-test-util-http -- -ra - py310-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.10 Ubuntu + py312-test-util-http_ubuntu-latest: + name: util-http 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py312-test-util-http -- -ra - py310-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.10 Ubuntu + py313-test-util-http_ubuntu-latest: + name: util-http 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-util-http -- -ra + + py314-test-util-http_ubuntu-latest: + name: util-http 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-util-http -- -ra + + pypy3-test-util-http_ubuntu-latest: + name: util-http pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-util-http -- -ra + + py39-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-exporter-credential-provider-gcp -- -ra + + py310-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-exporter-credential-provider-gcp -- -ra + + py311-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-exporter-credential-provider-gcp -- -ra + + py312-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-exporter-credential-provider-gcp -- -ra + + py313-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-exporter-credential-provider-gcp -- -ra + + py314-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-exporter-credential-provider-gcp -- -ra + + py39-test-util-genai_ubuntu-latest: + name: util-genai 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-util-genai -- -ra + + py310-test-util-genai_ubuntu-latest: + name: util-genai 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-util-genai -- -ra + + py311-test-util-genai_ubuntu-latest: + name: util-genai 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-util-genai -- -ra + + py312-test-util-genai_ubuntu-latest: + name: util-genai 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-util-genai -- -ra + + py313-test-util-genai_ubuntu-latest: + name: util-genai 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-util-genai -- -ra + + py314-test-util-genai_ubuntu-latest: + name: util-genai 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-util-genai -- -ra + + pypy3-test-util-genai_ubuntu-latest: + name: util-genai pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-util-genai -- -ra + + py39-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray-0 -- -ra + + py39-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray-1 -- -ra + + py310-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-propagator-aws-xray-0 -- -ra + + py310-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-propagator-aws-xray-1 -- -ra + + py311-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-propagator-aws-xray-0 -- -ra + + py311-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-propagator-aws-xray-1 -- -ra + + py312-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-propagator-aws-xray-0 -- -ra + + py312-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-propagator-aws-xray-1 -- -ra + + py313-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-propagator-aws-xray-0 -- -ra + + py313-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-propagator-aws-xray-1 -- -ra + + py314-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-propagator-aws-xray-0 -- -ra + + py314-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-propagator-aws-xray-1 -- -ra + + pypy3-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra + + pypy3-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra + + py39-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-propagator-ot-trace -- -ra + + py310-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-propagator-ot-trace -- -ra + + py311-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-propagator-ot-trace -- -ra + + py312-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-propagator-ot-trace -- -ra + + py313-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-propagator-ot-trace -- -ra + + py314-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-propagator-ot-trace -- -ra + + pypy3-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-propagator-ot-trace -- -ra + + py39-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-0-wrapt1 -- -ra + + py39-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + py39-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-1-wrapt1 -- -ra + + py39-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py310-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2272,10 +3051,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-0-wrapt1 -- -ra - py310-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.10 Ubuntu + py310-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2291,10 +3070,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-0-wrapt2 -- -ra - py310-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.10 Ubuntu + py310-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2310,10 +3089,29 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-1-wrapt1 -- -ra - py311-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.11 Ubuntu + py310-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py311-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2329,10 +3127,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py311-test-instrumentation-sio-pika-0-wrapt1 -- -ra - py311-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.11 Ubuntu + py311-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2348,10 +3146,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py311-test-instrumentation-sio-pika-0-wrapt2 -- -ra - py311-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.11 Ubuntu + py311-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2367,10 +3165,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py311-test-instrumentation-sio-pika-1-wrapt1 -- -ra - py311-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.11 Ubuntu + py311-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2386,10 +3184,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py311-test-instrumentation-sio-pika-1-wrapt2 -- -ra - py312-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.12 Ubuntu + py312-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2405,10 +3203,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py312-test-instrumentation-sio-pika-0-wrapt1 -- -ra - py312-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.12 Ubuntu + py312-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2424,10 +3222,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py312-test-instrumentation-sio-pika-0-wrapt2 -- -ra - py312-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.12 Ubuntu + py312-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2443,10 +3241,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py312-test-instrumentation-sio-pika-1-wrapt1 -- -ra - py312-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.12 Ubuntu + py312-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2462,10 +3260,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py312-test-instrumentation-sio-pika-1-wrapt2 -- -ra - py313-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.13 Ubuntu + py313-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2481,10 +3279,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py313-test-instrumentation-sio-pika-0-wrapt1 -- -ra - py313-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.13 Ubuntu + py313-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2500,10 +3298,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py313-test-instrumentation-sio-pika-0-wrapt2 -- -ra - py313-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.13 Ubuntu + py313-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2519,10 +3317,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py313-test-instrumentation-sio-pika-1-wrapt1 -- -ra - py313-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.13 Ubuntu + py313-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2538,10 +3336,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py313-test-instrumentation-sio-pika-1-wrapt2 -- -ra - py314-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.14 Ubuntu + py314-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2557,10 +3355,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py314-test-instrumentation-sio-pika-0-wrapt1 -- -ra - py314-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.14 Ubuntu + py314-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2576,10 +3374,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py314-test-instrumentation-sio-pika-0-wrapt2 -- -ra - py314-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.14 Ubuntu + py314-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2595,10 +3393,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py314-test-instrumentation-sio-pika-1-wrapt1 -- -ra - py314-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.14 Ubuntu + py314-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2614,143 +3412,295 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py314-test-instrumentation-sio-pika-1-wrapt2 -- -ra - pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 pypy-3.9 Ubuntu + pypy3-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + pypy3-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py39-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra + + py39-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra + + py39-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra + + py39-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra + + py310-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra + + py310-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra + + py310-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra - pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 pypy-3.9 Ubuntu + py310-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra - pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 pypy-3.9 Ubuntu + py311-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py311-test-instrumentation-aio-pika-0 -- -ra - pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 pypy-3.9 Ubuntu + py311-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py311-test-instrumentation-aio-pika-1 -- -ra - py39-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.9 Ubuntu + py311-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiokafka -- -ra + run: tox -e py311-test-instrumentation-aio-pika-2 -- -ra - py310-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.10 Ubuntu + py311-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-aiokafka -- -ra + run: tox -e py311-test-instrumentation-aio-pika-3 -- -ra - py311-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.11 Ubuntu + py312-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-aiokafka -- -ra + run: tox -e py312-test-instrumentation-aio-pika-0 -- -ra - py312-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.12 Ubuntu + py312-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -2766,238 +3716,238 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-aiokafka -- -ra + run: tox -e py312-test-instrumentation-aio-pika-1 -- -ra - py313-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.13 Ubuntu + py312-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-aiokafka -- -ra + run: tox -e py312-test-instrumentation-aio-pika-2 -- -ra - py314-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.14 Ubuntu + py312-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-aiokafka -- -ra + run: tox -e py312-test-instrumentation-aio-pika-3 -- -ra - pypy3-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka pypy-3.9 Ubuntu + py313-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-aiokafka -- -ra + run: tox -e py313-test-instrumentation-aio-pika-0 -- -ra - py39-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.9 Ubuntu + py313-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-kafka-python -- -ra + run: tox -e py313-test-instrumentation-aio-pika-1 -- -ra - py310-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.10 Ubuntu + py313-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-kafka-python -- -ra + run: tox -e py313-test-instrumentation-aio-pika-2 -- -ra - py311-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.11 Ubuntu + py313-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-kafka-python -- -ra + run: tox -e py313-test-instrumentation-aio-pika-3 -- -ra - py39-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.9 Ubuntu + py314-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py314-test-instrumentation-aio-pika-0 -- -ra - py310-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.10 Ubuntu + py314-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py314-test-instrumentation-aio-pika-1 -- -ra - py311-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.11 Ubuntu + py314-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py314-test-instrumentation-aio-pika-2 -- -ra - py312-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.12 Ubuntu + py314-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py314-test-instrumentation-aio-pika-3 -- -ra - py313-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.13 Ubuntu + pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-kafka-pythonng -- -ra + run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra - py314-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.14 Ubuntu + pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-kafka-pythonng -- -ra + run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra - pypy3-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python pypy-3.9 Ubuntu + pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3013,10 +3963,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-kafka-python -- -ra + run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra - pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng pypy-3.9 Ubuntu + pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3032,10 +3982,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra + run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra - py39-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.9 Ubuntu + py39-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3051,10 +4001,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-confluent-kafka -- -ra + run: tox -e py39-test-instrumentation-aiokafka -- -ra - py310-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.10 Ubuntu + py310-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3070,10 +4020,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-confluent-kafka -- -ra + run: tox -e py310-test-instrumentation-aiokafka -- -ra - py311-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.11 Ubuntu + py311-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3089,10 +4039,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-confluent-kafka -- -ra + run: tox -e py311-test-instrumentation-aiokafka -- -ra - py312-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.12 Ubuntu + py312-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3108,10 +4058,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-confluent-kafka -- -ra + run: tox -e py312-test-instrumentation-aiokafka -- -ra - py313-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.13 Ubuntu + py313-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3127,390 +4077,371 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-confluent-kafka -- -ra - - py314-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-confluent-kafka -- -ra - - py39-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.9 Ubuntu + run: tox -e py313-test-instrumentation-aiokafka -- -ra + + py314-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncio -- -ra + run: tox -e py314-test-instrumentation-aiokafka -- -ra - py310-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.10 Ubuntu + pypy3-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-asyncio -- -ra + run: tox -e pypy3-test-instrumentation-aiokafka -- -ra - py311-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.11 Ubuntu + py39-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-asyncio -- -ra + run: tox -e py39-test-instrumentation-kafka-python -- -ra - py312-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.12 Ubuntu + py310-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-asyncio -- -ra + run: tox -e py310-test-instrumentation-kafka-python -- -ra - py313-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.13 Ubuntu + py311-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-asyncio -- -ra + run: tox -e py311-test-instrumentation-kafka-python -- -ra - py314-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.14 Ubuntu + py39-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-asyncio -- -ra + run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra - py39-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.9 Ubuntu + py310-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-driver -- -ra + run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra - py39-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.9 Ubuntu + py311-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-scylla -- -ra + run: tox -e py311-test-instrumentation-kafka-pythonng -- -ra - py310-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.10 Ubuntu + py312-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-cassandra-driver -- -ra + run: tox -e py312-test-instrumentation-kafka-pythonng -- -ra - py310-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.10 Ubuntu + py313-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-cassandra-scylla -- -ra + run: tox -e py313-test-instrumentation-kafka-pythonng -- -ra - py311-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.11 Ubuntu + py314-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-cassandra-driver -- -ra + run: tox -e py314-test-instrumentation-kafka-pythonng -- -ra - py311-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.11 Ubuntu + pypy3-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py311-test-instrumentation-cassandra-scylla -- -ra + run: tox -e pypy3-test-instrumentation-kafka-python -- -ra - py312-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.12 Ubuntu + pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng pypy-3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python pypy-3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "pypy-3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-cassandra-driver -- -ra + run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra - py312-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.12 Ubuntu + py39-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.9" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py312-test-instrumentation-cassandra-scylla -- -ra + run: tox -e py39-test-instrumentation-confluent-kafka -- -ra - py313-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.13 Ubuntu + py310-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-cassandra-driver -- -ra + run: tox -e py310-test-instrumentation-confluent-kafka -- -ra - py313-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.13 Ubuntu + py311-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-instrumentation-cassandra-scylla -- -ra + run: tox -e py311-test-instrumentation-confluent-kafka -- -ra - py314-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.14 Ubuntu + py312-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-cassandra-driver -- -ra + run: tox -e py312-test-instrumentation-confluent-kafka -- -ra - py314-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.14 Ubuntu + py313-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra + run: tox -e py313-test-instrumentation-confluent-kafka -- -ra - pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu + py314-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra + run: tox -e py314-test-instrumentation-confluent-kafka -- -ra - py39-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.9 Ubuntu + py39-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3526,10 +4457,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra + run: tox -e py39-test-instrumentation-asyncio -- -ra - py310-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.10 Ubuntu + py310-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3545,10 +4476,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-processor-baggage -- -ra + run: tox -e py310-test-instrumentation-asyncio -- -ra - py311-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.11 Ubuntu + py311-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3564,10 +4495,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-processor-baggage -- -ra + run: tox -e py311-test-instrumentation-asyncio -- -ra - py312-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.12 Ubuntu + py312-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3583,10 +4514,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-processor-baggage -- -ra + run: tox -e py312-test-instrumentation-asyncio -- -ra - py313-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.13 Ubuntu + py313-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3602,10 +4533,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-processor-baggage -- -ra + run: tox -e py313-test-instrumentation-asyncio -- -ra - py314-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.14 Ubuntu + py314-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3621,29 +4552,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-processor-baggage -- -ra - - pypy3-test-processor-baggage_ubuntu-latest: - name: processor-baggage pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-processor-baggage -- -ra + run: tox -e py314-test-instrumentation-asyncio -- -ra - py39-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.9 Ubuntu + py39-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3659,10 +4571,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opamp-client-latest -- -ra + run: tox -e py39-test-instrumentation-cassandra-driver -- -ra - py39-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.9 Ubuntu + py39-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.9 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3678,10 +4590,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opamp-client-lowest -- -ra + run: tox -e py39-test-instrumentation-cassandra-scylla -- -ra - py310-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.10 Ubuntu + py310-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3697,10 +4609,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-opamp-client-latest -- -ra + run: tox -e py310-test-instrumentation-cassandra-driver -- -ra - py310-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.10 Ubuntu + py310-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3716,10 +4628,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-opamp-client-lowest -- -ra + run: tox -e py310-test-instrumentation-cassandra-scylla -- -ra - py311-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.11 Ubuntu + py311-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3735,10 +4647,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-opamp-client-latest -- -ra + run: tox -e py311-test-instrumentation-cassandra-driver -- -ra - py311-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.11 Ubuntu + py311-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3754,10 +4666,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py311-test-opamp-client-lowest -- -ra + run: tox -e py311-test-instrumentation-cassandra-scylla -- -ra - py312-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.12 Ubuntu + py312-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3773,10 +4685,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-opamp-client-latest -- -ra + run: tox -e py312-test-instrumentation-cassandra-driver -- -ra - py312-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.12 Ubuntu + py312-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3792,10 +4704,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py312-test-opamp-client-lowest -- -ra + run: tox -e py312-test-instrumentation-cassandra-scylla -- -ra - py313-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.13 Ubuntu + py313-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3811,10 +4723,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-opamp-client-latest -- -ra + run: tox -e py313-test-instrumentation-cassandra-driver -- -ra - py313-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.13 Ubuntu + py313-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3830,10 +4742,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py313-test-opamp-client-lowest -- -ra + run: tox -e py313-test-instrumentation-cassandra-scylla -- -ra - py314-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.14 Ubuntu + py314-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3849,10 +4761,10 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-opamp-client-latest -- -ra + run: tox -e py314-test-instrumentation-cassandra-driver -- -ra - py314-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.14 Ubuntu + py314-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3868,4 +4780,4 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py314-test-opamp-client-lowest -- -ra + run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra diff --git a/.github/workflows/test_3.yml b/.github/workflows/test_3.yml new file mode 100644 index 00000000000..933ffafa111 --- /dev/null +++ b/.github/workflows/test_3.yml @@ -0,0 +1,413 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Test 3 + +on: + push: + branches-ignore: + - 'release/*' + - 'otelbot/*' + pull_request: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +env: + # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' + # For PRs you can change the inner fallback ('main') + # For pushes you change the outer fallback ('main') + # The logic below is used during releases and depends on having an equivalent branch name in the core repo. + CORE_REPO_SHA: ${{ github.event_name == 'pull_request' && ( + contains(github.event.pull_request.labels.*.name, 'prepare-release') && github.event.pull_request.head.ref || + contains(github.event.pull_request.labels.*.name, 'backport') && github.event.pull_request.base.ref || + 'main' + ) || 'main' }} + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + + pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra + + py39-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-processor-baggage -- -ra + + py310-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-processor-baggage -- -ra + + py311-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-processor-baggage -- -ra + + py312-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-processor-baggage -- -ra + + py313-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-processor-baggage -- -ra + + py314-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-processor-baggage -- -ra + + pypy3-test-processor-baggage_ubuntu-latest: + name: processor-baggage pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-processor-baggage -- -ra + + py39-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opamp-client-latest -- -ra + + py39-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opamp-client-lowest -- -ra + + py310-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opamp-client-latest -- -ra + + py310-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opamp-client-lowest -- -ra + + py311-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opamp-client-latest -- -ra + + py311-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opamp-client-lowest -- -ra + + py312-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opamp-client-latest -- -ra + + py312-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opamp-client-lowest -- -ra + + py313-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opamp-client-latest -- -ra + + py313-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opamp-client-lowest -- -ra + + py314-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opamp-client-latest -- -ra + + py314-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opamp-client-lowest -- -ra diff --git a/CHANGELOG.md b/CHANGELOG.md index acc5bee1b02..8b3257fce7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 > Use [this search for a list of all CHANGELOG.md files in this repo](https://github.com/search?q=repo%3Aopen-telemetry%2Fopentelemetry-python-contrib+path%3A**%2FCHANGELOG.md&type=code). ## Unreleased - + ### Added - `opentelemetry-instrumentation-confluent-kafka`: Loosen confluent-kafka upper bound to <3.0.0 ([#4289](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4289)) +- `opentelemetry-instrumentation`: Add support for wrapt 2.x + ([#4203](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4203)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 0f777b75e40..2d6368350c8 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.5", "opentelemetry-instrumentation == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index 8f2c02638b2..7b851a402b5 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", "opentelemetry-util-http == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index ce36611a33e..1a8ad807b1f 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", "opentelemetry-util-http == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 204f10ecc88..cc3d33c23f9 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-instrumentation-dbapi == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py index 948050818c3..c2e3e7523c9 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py @@ -11,7 +11,7 @@ from opentelemetry.trace import SpanKind -# pylint: disable=abstract-method +# pylint: disable=abstract-method,no-member class AsyncProxyObject(wrapt.ObjectProxy): def __aiter__(self): return self.__wrapped__.__aiter__() @@ -54,7 +54,7 @@ async def wrapped_pool(self, create_pool_method, args, kwargs): def get_traced_connection_proxy( connection, db_api_integration, *args, **kwargs ): - # pylint: disable=abstract-method + # pylint: disable=abstract-method,no-member class TracedConnectionProxy(AsyncProxyObject): # pylint: disable=unused-argument def __init__(self, connection, *args, **kwargs): @@ -73,7 +73,7 @@ async def _cursor(self, *args, **kwargs): def get_traced_pool_proxy(pool, db_api_integration, *args, **kwargs): - # pylint: disable=abstract-method + # pylint: disable=abstract-method,no-member class TracedPoolProxy(AsyncProxyObject): # pylint: disable=unused-argument def __init__(self, pool, *args, **kwargs): @@ -125,7 +125,7 @@ async def traced_execution( def get_traced_cursor_proxy(cursor, db_api_integration, *args, **kwargs): _traced_cursor = AsyncCursorTracer(db_api_integration) - # pylint: disable=abstract-method + # pylint: disable=abstract-method,no-member class AsyncCursorTracerProxy(AsyncProxyObject): # pylint: disable=unused-argument def __init__(self, cursor, *args, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt1.txt new file mode 100644 index 00000000000..ae191f8ee50 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt2.txt new file mode 100644 index 00000000000..01c75bb94f4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index a3d94d65ee2..5c8b7448e0f 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -1,7 +1,6 @@ aiopg==1.4.0 asgiref==3.8.1 async-timeout==4.0.3 -Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 @@ -10,7 +9,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py b/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py index ab1fe53843a..e4cbd8ef412 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py @@ -472,7 +472,7 @@ def test_instrument_connection(self): connection2 = wrappers.instrument_connection( self.tracer, connection, "-" ) - self.assertIs(connection2.__wrapped__, connection) + self.assertIs(connection2.__wrapped__, connection) # pylint: disable=no-member def test_uninstrument_connection(self): connection = mock.Mock() @@ -482,7 +482,7 @@ def test_uninstrument_connection(self): connection2 = wrappers.instrument_connection( self.tracer, connection, "-" ) - self.assertIs(connection2.__wrapped__, connection) + self.assertIs(connection2.__wrapped__, connection) # pylint: disable=no-member connection3 = wrappers.uninstrument_connection(connection2) self.assertIs(connection3, connection) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index 16917716fef..bb7196168a9 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.14", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt1.txt new file mode 100644 index 00000000000..ae191f8ee50 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt2.txt new file mode 100644 index 00000000000..01c75bb94f4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index b2b4401d6b8..695688994f8 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -1,7 +1,6 @@ asgiref==3.8.1 async-timeout==4.0.3 asyncpg==0.30.0 -Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 @@ -9,7 +8,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-asyncpg diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py index 0fc44d6a23c..21d4591e0e7 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py @@ -3,7 +3,12 @@ import pytest from asyncpg import Connection, Record, cursor -from wrapt import ObjectProxy + +try: + # wrapt 2.0.0+ + from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from wrapt import ObjectProxy as BaseObjectProxy from opentelemetry import trace as trace_api from opentelemetry.instrumentation.asyncpg import AsyncPGInstrumentor @@ -50,7 +55,7 @@ def assert_wrapped(assert_fnc): for method_name in methods: method = getattr(cls, method_name, None) assert_fnc( - isinstance(method, ObjectProxy), + isinstance(method, BaseObjectProxy), f"{method} isinstance {type(method)}", ) diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index 4c8d569003a..3df8ab78fb1 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index 484e1a8cb2b..fb64bb46d71 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -30,6 +30,7 @@ dependencies = [ "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock_utils.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock_utils.py index 0b164b1f92a..930b4369421 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock_utils.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock_utils.py @@ -20,7 +20,12 @@ from typing import Any, Callable, Dict, Iterator, Sequence, Union from botocore.eventstream import EventStream, EventStreamError -from wrapt import ObjectProxy + +try: + # wrapt 2.0.0+ + from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from wrapt import ObjectProxy as BaseObjectProxy from opentelemetry._logs import LogRecord from opentelemetry.context import get_current @@ -37,7 +42,7 @@ # pylint: disable=abstract-method -class ConverseStreamWrapper(ObjectProxy): +class ConverseStreamWrapper(BaseObjectProxy): """Wrapper for botocore.eventstream.EventStream""" def __init__( @@ -61,7 +66,7 @@ def __init__( def __iter__(self): try: - for event in self.__wrapped__: + for event in self.__wrapped__: # pylint: disable=no-member self._process_event(event) yield event except EventStreamError as exc: @@ -143,7 +148,7 @@ def _process_event(self, event): return def close(self): - self.__wrapped__.close() + self.__wrapped__.close() # pylint: disable=no-member # Treat the stream as done to ensure the span end. self._complete_stream(self._response) @@ -157,7 +162,7 @@ def _handle_stream_error(self, exc): # pylint: disable=abstract-method -class InvokeModelWithResponseStreamWrapper(ObjectProxy): +class InvokeModelWithResponseStreamWrapper(BaseObjectProxy): """Wrapper for botocore.eventstream.EventStream""" def __init__( @@ -183,7 +188,7 @@ def __init__( self._ended = False def close(self): - self.__wrapped__.close() + self.__wrapped__.close() # pylint: disable=no-member # Treat the stream as done to ensure the span end. self._stream_done_callback(self._response, self._ended) @@ -197,7 +202,7 @@ def _handle_stream_error(self, exc): def __iter__(self): try: - for event in self.__wrapped__: + for event in self.__wrapped__: # pylint: disable=no-member self._process_event(event) yield event except EventStreamError as exc: diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt1.txt new file mode 100644 index 00000000000..57149ca01e4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements-0.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt2.txt new file mode 100644 index 00000000000..7ac79812946 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements-0.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt index f6243241bd7..4e084ef0cef 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt @@ -6,7 +6,6 @@ certifi==2024.7.4 cffi==1.17.0 charset-normalizer==3.3.2 cryptography==43.0.1 -Deprecated==1.2.14 docker==7.0.0 idna==3.7 iniconfig==2.0.0 @@ -31,7 +30,6 @@ tomli==2.0.1 typing_extensions==4.12.2 urllib3==1.26.19 Werkzeug==3.0.6 -wrapt==1.16.0 xmltodict==0.13.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt1.txt new file mode 100644 index 00000000000..eb6190d00df --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements-1.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt2.txt new file mode 100644 index 00000000000..eaac680e2eb --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements-1.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt index 5c7cb24a0c3..6cc42f92a78 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt @@ -6,7 +6,6 @@ certifi==2024.7.4 cffi==1.17.0 charset-normalizer==3.3.2 cryptography==43.0.1 -Deprecated==1.2.14 docker==7.0.0 idna==3.7 iniconfig==2.0.0 @@ -31,7 +30,6 @@ tomli==2.0.1 typing_extensions==4.12.2 urllib3==1.26.19 Werkzeug==3.0.6 -wrapt==1.16.0 xmltodict==0.13.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 4c7c92203f1..d919e124699 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml index 6d7c5025479..bfa83b6f895 100644 --- a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index fb1f4ac8971..2f1ea1e380b 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ dependencies = [ "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-api ~= 1.12", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index ade1be720e0..6fd52f5ff09 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py index cd154616a6c..9eb386b0eaa 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -173,9 +173,14 @@ import re from typing import Any, Awaitable, Callable, Generic, TypeVar -import wrapt from wrapt import wrap_function_wrapper +try: + # wrapt 2.0.0+ + from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from wrapt import ObjectProxy as BaseObjectProxy + from opentelemetry import trace as trace_api from opentelemetry.instrumentation.dbapi.version import __version__ from opentelemetry.instrumentation.sqlcommenter_utils import _add_sql_comment @@ -372,7 +377,7 @@ def instrument_connection( Returns: An instrumented connection. """ - if isinstance(connection, wrapt.ObjectProxy): + if isinstance(connection, BaseObjectProxy): _logger.warning("Connection already instrumented") return connection @@ -407,7 +412,7 @@ def uninstrument_connection( Returns: An uninstrumented connection. """ - if isinstance(connection, wrapt.ObjectProxy): + if isinstance(connection, BaseObjectProxy): return connection.__wrapped__ _logger.warning("Connection is not instrumented") @@ -565,15 +570,15 @@ def get_connection_attributes(self, connection: object) -> None: self.span_attributes[NET_PEER_PORT] = port -# pylint: disable=abstract-method -class TracedConnectionProxy(wrapt.ObjectProxy, Generic[ConnectionT]): +# pylint: disable=abstract-method,no-member +class TracedConnectionProxy(BaseObjectProxy, Generic[ConnectionT]): # pylint: disable=unused-argument def __init__( self, connection: ConnectionT, db_api_integration: DatabaseApiIntegration | None = None, ): - wrapt.ObjectProxy.__init__(self, connection) + BaseObjectProxy.__init__(self, connection) self._self_db_api_integration = db_api_integration def __getattribute__(self, name: str): @@ -799,15 +804,15 @@ async def traced_execution_async( return await query_method(*args, **kwargs) -# pylint: disable=abstract-method -class TracedCursorProxy(wrapt.ObjectProxy, Generic[CursorT]): +# pylint: disable=abstract-method,no-member +class TracedCursorProxy(BaseObjectProxy, Generic[CursorT]): # pylint: disable=unused-argument def __init__( self, cursor: CursorT, db_api_integration: DatabaseApiIntegration, ): - wrapt.ObjectProxy.__init__(self, cursor) + BaseObjectProxy.__init__(self, cursor) self._self_cursor_tracer = CursorTracer[CursorT](db_api_integration) def execute(self, *args: Any, **kwargs: Any): diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt1.txt new file mode 100644 index 00000000000..ae191f8ee50 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt2.txt new file mode 100644 index 00000000000..01c75bb94f4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt index a05fd86be5c..249a7eab039 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt @@ -1,5 +1,4 @@ asgiref==3.8.1 -Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 pluggy==1.5.0 @@ -7,7 +6,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-dbapi diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index f9fb9c952b7..2b6ed0e478c 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -1052,7 +1052,7 @@ def test_wrap_connect(self, mock_dbapi): dbapi.wrap_connect(self.tracer, mock_dbapi, "connect", "-") connection = mock_dbapi.connect() self.assertEqual(mock_dbapi.connect.call_count, 1) - self.assertIsInstance(connection.__wrapped__, mock.Mock) + self.assertIsInstance(connection.__wrapped__, mock.Mock) # pylint: disable=no-member @mock.patch("opentelemetry.instrumentation.dbapi") def test_unwrap_connect(self, mock_dbapi): @@ -1071,7 +1071,7 @@ def test_instrument_connection(self): connection2 = dbapi.instrument_connection( "instrumenting_module_test_name", mocked_conn, "dbname" ) - self.assertIs(connection2.__wrapped__, mocked_conn) + self.assertIs(connection2.__wrapped__, mocked_conn) # pylint: disable=no-member @mock.patch("opentelemetry.instrumentation.dbapi.DatabaseApiIntegration") def test_instrument_connection_kwargs_defaults(self, mock_dbapiint): @@ -1138,7 +1138,7 @@ def test_uninstrument_connection(self): connection2 = dbapi.instrument_connection( "instrumenting_module_test_name", mocked_conn, "-" ) - self.assertIs(connection2.__wrapped__, mocked_conn) + self.assertIs(connection2.__wrapped__, mocked_conn) # pylint: disable=no-member connection3 = dbapi.uninstrument_connection(connection2) self.assertIs(connection3, mocked_conn) diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index 9780e16b10b..c30509f28f0 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index 9d6160919aa..b5b1a3cab05 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_aio_server.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_aio_server.py index 73a7c16c08c..8ee022f33a7 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_aio_server.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_aio_server.py @@ -14,7 +14,12 @@ import grpc import grpc.aio -import wrapt + +try: + # wrapt 2.0.0+ + from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from wrapt import ObjectProxy as BaseObjectProxy from opentelemetry.semconv._incubating.attributes.rpc_attributes import ( RPC_GRPC_STATUS_CODE, @@ -24,8 +29,8 @@ from ._utilities import _server_status -# pylint:disable=abstract-method -class _OpenTelemetryAioServicerContext(wrapt.ObjectProxy): +# pylint:disable=abstract-method,no-member +class _OpenTelemetryAioServicerContext(BaseObjectProxy): def __init__(self, servicer_context, active_span): super().__init__(servicer_context) self._self_active_span = active_span diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt1.txt new file mode 100644 index 00000000000..57149ca01e4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements-0.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt2.txt new file mode 100644 index 00000000000..7ac79812946 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements-0.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt index 3e688b45c25..9ab63cbe445 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt @@ -1,5 +1,4 @@ asgiref==3.8.1 -Deprecated==1.2.14 grpcio==1.62.0 iniconfig==2.0.0 packaging==24.0 @@ -9,7 +8,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-grpc diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt1.txt new file mode 100644 index 00000000000..eb6190d00df --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements-1.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt2.txt new file mode 100644 index 00000000000..eaac680e2eb --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements-1.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt index 48def42151c..bbb4e65ebd5 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -1,5 +1,4 @@ asgiref==3.8.1 -Deprecated==1.2.14 grpcio==1.75.1 iniconfig==2.0.0 packaging==24.0 @@ -9,7 +8,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-grpc diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 2d09960f4cb..0ee95e83108 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", "opentelemetry-util-http == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt1.txt new file mode 100644 index 00000000000..57149ca01e4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements-0.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt2.txt new file mode 100644 index 00000000000..7ac79812946 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements-0.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index b663f4566b1..9ecea68c2f2 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -1,7 +1,6 @@ anyio==3.7.1 asgiref==3.8.1 certifi==2024.7.4 -Deprecated==1.2.14 exceptiongroup==1.2.0 h11==0.12.0 httpcore==0.13.7 @@ -17,7 +16,6 @@ rfc3986==1.5.0 sniffio==1.3.1 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt1.txt new file mode 100644 index 00000000000..eb6190d00df --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements-1.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt2.txt new file mode 100644 index 00000000000..eaac680e2eb --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements-1.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index e8039e691c6..757bc643299 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -1,7 +1,6 @@ anyio==4.3.0 asgiref==3.8.1 certifi==2024.7.4 -Deprecated==1.2.14 exceptiongroup==1.2.0 h11==0.16 httpcore==1.0.9 @@ -16,7 +15,6 @@ respx==0.22.0 sniffio==1.3.1 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py index 7b0d3164f94..91ade3a94ab 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py @@ -22,7 +22,12 @@ import httpx import respx -from wrapt import ObjectProxy + +try: + # wrapt 2.0.0+ + from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from wrapt import ObjectProxy as BaseObjectProxy import opentelemetry.instrumentation.httpx from opentelemetry import trace @@ -1482,7 +1487,7 @@ def assert_proxy_mounts(self, mounts, num_mounts, transport_type=None): else: handler = self.get_transport_handler(transport) self.assertTrue( - isinstance(handler, ObjectProxy) + isinstance(handler, BaseObjectProxy) and getattr(handler, "__wrapped__") ) @@ -2082,13 +2087,13 @@ class CustomClient(httpx.Client): client = CustomClient() self.assertFalse( - isinstance(client._transport.handle_request, ObjectProxy) + isinstance(client._transport.handle_request, BaseObjectProxy) ) HTTPXClientInstrumentor().instrument() self.assertTrue( - isinstance(client._transport.handle_request, ObjectProxy) + isinstance(client._transport.handle_request, BaseObjectProxy) ) @@ -2177,11 +2182,11 @@ class CustomAsyncClient(httpx.AsyncClient): client = CustomAsyncClient() self.assertFalse( - isinstance(client._transport.handle_async_request, ObjectProxy) + isinstance(client._transport.handle_async_request, BaseObjectProxy) ) HTTPXClientInstrumentor().instrument() self.assertTrue( - isinstance(client._transport.handle_async_request, ObjectProxy) + isinstance(client._transport.handle_async_request, BaseObjectProxy) ) diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index c2b6d2592ea..c9ae526c74b 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 1658d67100c..875e0556804 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-api ~= 1.5", "packaging >= 20.0", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/utils.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/utils.py index ff3ac86ac50..b7f11174297 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/utils.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/utils.py @@ -7,7 +7,12 @@ ) from pika.channel import Channel from pika.spec import Basic, BasicProperties -from wrapt import ObjectProxy + +try: + # wrapt 2.0.0+ + from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from wrapt import ObjectProxy as BaseObjectProxy from opentelemetry import context, propagate, trace from opentelemetry.instrumentation.utils import is_instrumentation_enabled @@ -196,7 +201,7 @@ def _enrich_span( # pylint:disable=abstract-method -class ReadyMessagesDequeProxy(ObjectProxy): +class ReadyMessagesDequeProxy(BaseObjectProxy): def __init__( self, wrapped, @@ -218,7 +223,7 @@ def popleft(self, *args, **kwargs): except Exception as inst_exception: # pylint: disable=W0703 _LOG.exception(inst_exception) - evt = self.__wrapped__.popleft(*args, **kwargs) + evt = self.__wrapped__.popleft(*args, **kwargs) # pylint:disable=no-member try: # If a new message was received, create a span and set as active context diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt1.txt new file mode 100644 index 00000000000..57149ca01e4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements-0.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt2.txt new file mode 100644 index 00000000000..7ac79812946 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements-0.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt index 3e2f26b098b..fca0d25b881 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt @@ -1,5 +1,4 @@ asgiref==3.8.1 -Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 pika==0.13.1 @@ -8,7 +7,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pika diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt1.txt new file mode 100644 index 00000000000..eb6190d00df --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements-1.txt +wrapt==1.17.3 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt2.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt2.txt new file mode 100644 index 00000000000..eaac680e2eb --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements-1.txt +wrapt==2.1.2 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt index 9ad521943f4..50fd870f9e6 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt @@ -1,5 +1,4 @@ asgiref==3.8.1 -Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 pika==1.3.2 @@ -8,7 +7,6 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-pika diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index aa346600483..0d2217d6a68 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 2f742f0e5bc..b5840991fc6 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ "opentelemetry-instrumentation-wsgi == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", "opentelemetry-util-http == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 7f692ade898..ab3f7bc5954 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-instrumentation == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index 5ef7097c637..6fc08d3c8a8 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ "opentelemetry-instrumentation == 0.62b0.dev", "opentelemetry-semantic-conventions == 0.62b0.dev", "opentelemetry-util-http == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.optional-dependencies] diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index e628f6cd656..dd044ce2baa 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.4", "opentelemetry-semantic-conventions == 0.62b0.dev", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", "packaging >= 18.0", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py index e38932e28dc..37e6c674f91 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py @@ -20,7 +20,11 @@ from re import escape, sub from typing import Any, Dict, Generator, Sequence -from wrapt import ObjectProxy +try: + # wrapt 2.0.0+ + from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from wrapt import ObjectProxy as BaseObjectProxy from opentelemetry import context, trace @@ -108,7 +112,11 @@ def unwrap(obj: object, attr: str): ) from exc func = getattr(obj, attr, None) - if func and isinstance(func, ObjectProxy) and hasattr(func, "__wrapped__"): + if ( + func + and isinstance(func, BaseObjectProxy) + and hasattr(func, "__wrapped__") + ): setattr(obj, attr, func.__wrapped__) diff --git a/opentelemetry-instrumentation/test-requirements-wrapt1.txt b/opentelemetry-instrumentation/test-requirements-wrapt1.txt new file mode 100644 index 00000000000..ae191f8ee50 --- /dev/null +++ b/opentelemetry-instrumentation/test-requirements-wrapt1.txt @@ -0,0 +1,2 @@ +-r test-requirements.txt +wrapt==1.17.3 diff --git a/opentelemetry-instrumentation/test-requirements-wrapt2.txt b/opentelemetry-instrumentation/test-requirements-wrapt2.txt new file mode 100644 index 00000000000..01c75bb94f4 --- /dev/null +++ b/opentelemetry-instrumentation/test-requirements-wrapt2.txt @@ -0,0 +1,2 @@ +-r test-requirements.txt +wrapt==2.1.2 diff --git a/opentelemetry-instrumentation/test-requirements.txt b/opentelemetry-instrumentation/test-requirements.txt index 58c09a950b3..d8088387a24 100644 --- a/opentelemetry-instrumentation/test-requirements.txt +++ b/opentelemetry-instrumentation/test-requirements.txt @@ -1,5 +1,4 @@ asgiref==3.8.1 -Deprecated==1.2.14 gevent==25.5.1 iniconfig==2.0.0 packaging==24.0 @@ -8,6 +7,5 @@ py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 typing_extensions==4.12.2 -wrapt==1.16.0 zipp==3.19.2 -e opentelemetry-instrumentation diff --git a/opentelemetry-instrumentation/tests/test_utils.py b/opentelemetry-instrumentation/tests/test_utils.py index 5ddd45d6927..11a3598bdc0 100644 --- a/opentelemetry-instrumentation/tests/test_utils.py +++ b/opentelemetry-instrumentation/tests/test_utils.py @@ -15,7 +15,13 @@ import unittest from http import HTTPStatus -from wrapt import ObjectProxy, wrap_function_wrapper +from wrapt import wrap_function_wrapper + +try: + # wrapt 2.0.0+ + from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from wrapt import ObjectProxy as BaseObjectProxy from opentelemetry.context import ( _SUPPRESS_HTTP_INSTRUMENTATION_KEY, @@ -263,23 +269,23 @@ def _wrap_method(): def test_can_unwrap_object_attribute(self): self._wrap_method() instance = WrappedClass() - self.assertTrue(isinstance(instance.method, ObjectProxy)) + self.assertTrue(isinstance(instance.method, BaseObjectProxy)) unwrap(WrappedClass, "method") - self.assertFalse(isinstance(instance.method, ObjectProxy)) + self.assertFalse(isinstance(instance.method, BaseObjectProxy)) def test_can_unwrap_object_attribute_as_string(self): self._wrap_method() instance = WrappedClass() - self.assertTrue(isinstance(instance.method, ObjectProxy)) + self.assertTrue(isinstance(instance.method, BaseObjectProxy)) unwrap("tests.test_utils.WrappedClass", "method") - self.assertFalse(isinstance(instance.method, ObjectProxy)) + self.assertFalse(isinstance(instance.method, BaseObjectProxy)) def test_raises_import_error_if_path_not_well_formed(self): self._wrap_method() instance = WrappedClass() - self.assertTrue(isinstance(instance.method, ObjectProxy)) + self.assertTrue(isinstance(instance.method, BaseObjectProxy)) with self.assertRaisesRegex( ImportError, "Cannot parse '' as dotted import path" @@ -287,23 +293,23 @@ def test_raises_import_error_if_path_not_well_formed(self): unwrap("", "method") unwrap(WrappedClass, "method") - self.assertFalse(isinstance(instance.method, ObjectProxy)) + self.assertFalse(isinstance(instance.method, BaseObjectProxy)) def test_raises_import_error_if_cannot_find_module(self): self._wrap_method() instance = WrappedClass() - self.assertTrue(isinstance(instance.method, ObjectProxy)) + self.assertTrue(isinstance(instance.method, BaseObjectProxy)) with self.assertRaisesRegex(ImportError, "No module named 'does'"): unwrap("does.not.exist.WrappedClass", "method") unwrap(WrappedClass, "method") - self.assertFalse(isinstance(instance.method, ObjectProxy)) + self.assertFalse(isinstance(instance.method, BaseObjectProxy)) def test_raises_import_error_if_cannot_find_object(self): self._wrap_method() instance = WrappedClass() - self.assertTrue(isinstance(instance.method, ObjectProxy)) + self.assertTrue(isinstance(instance.method, BaseObjectProxy)) with self.assertRaisesRegex( ImportError, "Cannot import 'NotWrappedClass' from" @@ -311,7 +317,7 @@ def test_raises_import_error_if_cannot_find_object(self): unwrap("tests.test_utils.NotWrappedClass", "method") unwrap(WrappedClass, "method") - self.assertFalse(isinstance(instance.method, ObjectProxy)) + self.assertFalse(isinstance(instance.method, BaseObjectProxy)) # pylint: disable=no-self-use def test_does_nothing_if_cannot_find_attribute(self): @@ -320,6 +326,6 @@ def test_does_nothing_if_cannot_find_attribute(self): def test_does_nothing_if_attribute_is_not_from_wrapt(self): instance = WrappedClass() - self.assertFalse(isinstance(instance.method, ObjectProxy)) + self.assertFalse(isinstance(instance.method, BaseObjectProxy)) unwrap(WrappedClass, "method") - self.assertFalse(isinstance(instance.method, ObjectProxy)) + self.assertFalse(isinstance(instance.method, BaseObjectProxy)) diff --git a/processor/opentelemetry-processor-baggage/pyproject.toml b/processor/opentelemetry-processor-baggage/pyproject.toml index 2c4098aeb61..31f8ddfb7a5 100644 --- a/processor/opentelemetry-processor-baggage/pyproject.toml +++ b/processor/opentelemetry-processor-baggage/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.5", "opentelemetry-sdk ~= 1.5", - "wrapt >= 1.0.0, < 2.0.0", + "wrapt >= 1.0.0, < 3.0.0", ] [project.urls] diff --git a/tox.ini b/tox.ini index 7a21521de08..062dbfc74d1 100644 --- a/tox.ini +++ b/tox.ini @@ -63,8 +63,8 @@ envlist = lint-distro ; opentelemetry-instrumentation - py3{9,10,11,12,13,14}-test-opentelemetry-instrumentation - pypy3-test-opentelemetry-instrumentation + py3{9,10,11,12,13,14}-test-opentelemetry-instrumentation-{wrapt1,wrapt2} + pypy3-test-opentelemetry-instrumentation-wrapt2 lint-opentelemetry-instrumentation ; opentelemetry-instrumentation-aiohttp-client @@ -78,7 +78,7 @@ envlist = lint-instrumentation-aiohttp-server ; opentelemetry-instrumentation-aiopg - py3{9,10,11,12,13,14}-test-instrumentation-aiopg + py3{9,10,11,12,13,14}-test-instrumentation-aiopg-{wrapt1,wrapt2} ; instrumentation-aiopg intentionally excluded from pypy3 lint-instrumentation-aiopg @@ -88,7 +88,7 @@ envlist = lint-instrumentation-aws-lambda ; opentelemetry-instrumentation-botocore - py3{9,10,11,12,13,14}-test-instrumentation-botocore-{0,1} + py3{9,10,11,12,13,14}-test-instrumentation-botocore-{0,1}-{wrapt1,wrapt2} ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 ; pypy3-test-instrumentation-botocore lint-instrumentation-botocore @@ -115,8 +115,8 @@ envlist = lint-instrumentation-django ; opentelemetry-instrumentation-dbapi - py3{9,10,11,12,13,14}-test-instrumentation-dbapi - pypy3-test-instrumentation-dbapi + py3{9,10,11,12,13,14}-test-instrumentation-dbapi-{wrapt1,wrapt2} + pypy3-test-instrumentation-dbapi-wrapt2 lint-instrumentation-dbapi ; opentelemetry-instrumentation-boto @@ -291,7 +291,7 @@ envlist = lint-instrumentation-asgi ; opentelemetry-instrumentation-asyncpg - py3{9,10,11,12,13,14}-test-instrumentation-asyncpg + py3{9,10,11,12,13,14}-test-instrumentation-asyncpg-{wrapt1,wrapt2} ; ext-asyncpg intentionally excluded from pypy3 lint-instrumentation-asyncpg @@ -311,8 +311,8 @@ envlist = ; 0: grpcio==1.62.0 ; 1: grpcio==1.75.1 ; TODO #4201 simplify tests-requirements here to use latest|oldest testing pattern - py3{9,10,11,12}-test-instrumentation-grpc-{0,1} - py3{13,14}-test-instrumentation-grpc-1 + py3{9,10,11,12}-test-instrumentation-grpc-{0,1}-{wrapt1,wrapt2} + py3{13,14}-test-instrumentation-grpc-1-{wrapt1,wrapt2} lint-instrumentation-grpc ; opentelemetry-instrumentation-sqlalchemy @@ -366,9 +366,9 @@ envlist = ; below mean these dependencies are being used: ; 0: httpx>=0.18.0,<0.19.0 respx~=0.17.0 ; 1: httpx>=0.19.0 respx~=0.20.1 - py3{9,10,11,12}-test-instrumentation-httpx-{0,1} - py3{13,14}-test-instrumentation-httpx-1 - pypy3-test-instrumentation-httpx-{0,1} + py3{9,10,11,12}-test-instrumentation-httpx-{0,1}-{wrapt1,wrapt2} + py3{13,14}-test-instrumentation-httpx-1-{wrapt1,wrapt2} + pypy3-test-instrumentation-httpx-{0,1}-wrapt2 lint-instrumentation-httpx ; opentelemetry-util-http @@ -401,8 +401,8 @@ envlist = ; below mean these dependencies are being used: ; 0: pika>=0.12.0,<1.0.0 ; 1: pika>=1.0.0 - py3{9,10,11,12,13,14}-test-instrumentation-sio-pika-{0,1} - pypy3-test-instrumentation-sio-pika-{0,1} + py3{9,10,11,12,13,14}-test-instrumentation-sio-pika-{0,1}-{wrapt1,wrapt2} + pypy3-test-instrumentation-sio-pika-{0,1}-wrapt2 lint-instrumentation-sio-pika ; opentelemetry-instrumentation-aio-pika @@ -474,7 +474,9 @@ deps = coverage: pytest-cov opentelemetry-instrumentation: {[testenv]test_deps} - opentelemetry-instrumentation: -r {toxinidir}/opentelemetry-instrumentation/test-requirements.txt + opentelemetry-instrumentation-wrapt1: -r {toxinidir}/opentelemetry-instrumentation/test-requirements-wrapt1.txt + opentelemetry-instrumentation-wrapt2: -r {toxinidir}/opentelemetry-instrumentation/test-requirements-wrapt2.txt + lint-opentelemetry-instrumentation: -r {toxinidir}/opentelemetry-instrumentation/test-requirements-wrapt2.txt distro: {[testenv]test_deps} distro: -r {toxinidir}/opentelemetry-distro/test-requirements.txt @@ -527,9 +529,11 @@ deps = click: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt sio-pika: {[testenv]test_deps} - sio-pika-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt - sio-pika-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt - lint-instrumentation-sio-pika: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt + sio-pika-0-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt1.txt + sio-pika-0-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0-wrapt2.txt + sio-pika-1-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt1.txt + sio-pika-1-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt2.txt + lint-instrumentation-sio-pika: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1-wrapt2.txt aio-pika: {[testenv]test_deps} aio-pika-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -551,15 +555,19 @@ deps = confluent-kafka: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt grpc: {[testenv]test_deps} - grpc-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt - grpc-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt - lint-instrumentation-grpc: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt + grpc-0-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt1.txt + grpc-0-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0-wrapt2.txt + grpc-1-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt1.txt + grpc-1-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt2.txt + lint-instrumentation-grpc: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1-wrapt2.txt wsgi: {[testenv]test_deps} wsgi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt asyncpg: {[testenv]test_deps} - asyncpg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt + asyncpg-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt1.txt + asyncpg-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt2.txt + lint-instrumentation-asyncpg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements-wrapt2.txt aws-lambda: {[testenv]test_deps} aws-lambda: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt @@ -594,9 +602,11 @@ deps = lint-instrumentation-urllib3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt botocore: {[testenv]test_deps} - botocore-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt - botocore-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt - lint-instrumentation-botocore: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt + botocore-0-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt1.txt + botocore-0-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt2.txt + botocore-1-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt1.txt + botocore-1-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt2.txt + lint-instrumentation-botocore: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt2.txt cassandra: {[testenv]test_deps} cassandra-driver: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt @@ -604,7 +614,9 @@ deps = lint-instrumentation-cassandra: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt dbapi: {[testenv]test_deps} - dbapi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt + dbapi-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt1.txt + dbapi-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt2.txt + lint-instrumentation-dbapi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt2.txt django: {[testenv]test_deps} py3{9}-test-instrumentation-django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -701,7 +713,9 @@ deps = aiohttp-server: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt aiopg: {[testenv]test_deps} - aiopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt + aiopg-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt1.txt + aiopg-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt2.txt + lint-instrumentation-aiopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements-wrapt2.txt richconsole: {[testenv]test_deps} richconsole: -r {toxinidir}/exporter/opentelemetry-exporter-richconsole/test-requirements.txt @@ -725,9 +739,11 @@ deps = asyncio: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt httpx: {[testenv]test_deps} - httpx-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt - httpx-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt - lint-instrumentation-httpx: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt + httpx-0-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt1.txt + httpx-0-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0-wrapt2.txt + httpx-1-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt1.txt + httpx-1-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt2.txt + lint-instrumentation-httpx: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1-wrapt2.txt # packages that are released individually should provide a test-requirements.txt with the lowest version of OTel API # and SDK supported to test we are honoring it diff --git a/uv.lock b/uv.lock index 826755f784d..404d798da1e 100644 --- a/uv.lock +++ b/uv.lock @@ -2707,7 +2707,7 @@ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "packaging", specifier = ">=18.0" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] [[package]] @@ -2729,7 +2729,7 @@ requires-dist = [ { name = "aio-pika", marker = "extra == 'instruments'", specifier = ">=7.2.0,<10.0.0" }, { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -2756,7 +2756,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "opentelemetry-util-http", editable = "util/opentelemetry-util-http" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -2783,7 +2783,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "opentelemetry-util-http", editable = "util/opentelemetry-util-http" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -2833,7 +2833,7 @@ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-instrumentation-dbapi", editable = "instrumentation/opentelemetry-instrumentation-dbapi" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -2932,7 +2932,7 @@ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3020,7 +3020,7 @@ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3032,6 +3032,7 @@ dependencies = [ { name = "opentelemetry-instrumentation" }, { name = "opentelemetry-propagator-aws-xray" }, { name = "opentelemetry-semantic-conventions" }, + { name = "wrapt" }, ] [package.optional-dependencies] @@ -3046,6 +3047,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-propagator-aws-xray", editable = "propagator/opentelemetry-propagator-aws-xray" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3072,7 +3074,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "scylla-driver", marker = "extra == 'instruments-any'", specifier = "~=3.25" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments", "instruments-any"] @@ -3145,7 +3147,7 @@ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3168,7 +3170,7 @@ requires-dist = [ { name = "confluent-kafka", marker = "extra == 'instruments'", specifier = ">=1.8.2,<3.0.0" }, { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3187,7 +3189,7 @@ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3244,7 +3246,7 @@ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3379,7 +3381,7 @@ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3406,7 +3408,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "opentelemetry-util-http", editable = "util/opentelemetry-util-http" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3429,7 +3431,7 @@ requires-dist = [ { name = "jinja2", marker = "extra == 'instruments'", specifier = ">=2.7,<4.0" }, { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3609,7 +3611,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "packaging", specifier = ">=20.0" }, { name = "pika", marker = "extra == 'instruments'", specifier = ">=0.12.0" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3682,7 +3684,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "pymemcache", marker = "extra == 'instruments'", specifier = ">=1.3.5,<5" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3780,7 +3782,7 @@ requires-dist = [ { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "opentelemetry-util-http", editable = "util/opentelemetry-util-http" }, { name = "pyramid", marker = "extra == 'instruments'", specifier = ">=1.7" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -3965,7 +3967,7 @@ dependencies = [ requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] @@ -4061,7 +4063,7 @@ requires-dist = [ { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "opentelemetry-util-http", editable = "util/opentelemetry-util-http" }, { name = "urllib3", marker = "extra == 'instruments'", specifier = ">=1.0.0,<3.0.0" }, - { name = "wrapt", specifier = ">=1.0.0,<2.0.0" }, + { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] provides-extras = ["instruments"] From f99d6d59a08b3e3b12c5fa203d2541ddb9a2d512 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 12 Mar 2026 09:38:17 +0100 Subject: [PATCH 12/78] Remove boto instrumentation (#4303) * Remove boto instrumentation * Add changelog * Run tox -e generate --- .github/workflows/core_contrib_test_0.yml | 30 -- .github/workflows/lint_0.yml | 19 -- .github/workflows/test_0.yml | 114 +++---- .github/workflows/test_1.yml | 114 +++---- .github/workflows/test_2.yml | 114 +++---- .github/workflows/test_3.yml | 57 ---- CHANGELOG.md | 5 + docs-requirements.txt | 1 - docs/instrumentation/boto/boto.rst | 7 - eachdist.ini | 3 - instrumentation/README.md | 1 - .../LICENSE | 201 ------------ .../README.rst | 24 -- .../pyproject.toml | 55 ---- .../instrumentation/boto/__init__.py | 252 ---------------- .../instrumentation/boto/package.py | 16 - .../instrumentation/boto/version.py | 15 - .../test-requirements.txt | 37 --- .../tests/__init__.py | 0 .../tests/conftest.py | 31 -- .../tests/test_boto_instrumentation.py | 285 ------------------ .../pyproject.toml | 1 - .../instrumentation/bootstrap_gen.py | 4 - pyproject.toml | 2 - tox.ini | 12 - uv.lock | 35 --- 26 files changed, 176 insertions(+), 1259 deletions(-) delete mode 100644 docs/instrumentation/boto/boto.rst delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/LICENSE delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/README.rst delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/pyproject.toml delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/package.py delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/tests/__init__.py delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/tests/conftest.py delete mode 100644 instrumentation/opentelemetry-instrumentation-boto/tests/test_boto_instrumentation.py diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index 47d0196cd04..019d2327e2a 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -957,36 +957,6 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra - py39-test-instrumentation-boto: - name: instrumentation-boto - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} - uses: actions/checkout@v4 - with: - repository: open-telemetry/opentelemetry-python-contrib - ref: ${{ env.CONTRIB_REPO_SHA }} - - - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} - uses: actions/checkout@v4 - with: - repository: open-telemetry/opentelemetry-python - ref: ${{ env.CORE_REPO_SHA }} - path: opentelemetry-python - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - architecture: "x64" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-boto -- -ra - py39-test-instrumentation-asyncclick: name: instrumentation-asyncclick runs-on: ubuntu-latest diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index f43075df89c..bfdbc0d81e2 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -393,25 +393,6 @@ jobs: - name: Run tests run: tox -e lint-instrumentation-dbapi - lint-instrumentation-boto: - name: instrumentation-boto - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e lint-instrumentation-boto - lint-instrumentation-asyncclick: name: instrumentation-asyncclick runs-on: ubuntu-latest diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index a8442aeecfd..c867d4a3306 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -4079,63 +4079,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-dbapi-wrapt2 -- -ra - py39-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-boto -- -ra - - py310-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-boto -- -ra - - py311-test-instrumentation-boto_ubuntu-latest: - name: instrumentation-boto 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-boto -- -ra - py39-test-instrumentation-asyncclick_ubuntu-latest: name: instrumentation-asyncclick 3.9 Ubuntu runs-on: ubuntu-latest @@ -4781,3 +4724,60 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra + + pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra + + py39-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-0 -- -ra + + py39-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-1 -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index d6ae260e936..80ba04b5454 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -32,63 +32,6 @@ env: jobs: - pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra - - py39-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra - - py39-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra - py39-test-instrumentation-falcon-2_ubuntu-latest: name: instrumentation-falcon-2 3.9 Ubuntu runs-on: ubuntu-latest @@ -4781,3 +4724,60 @@ jobs: - name: Run tests run: tox -e py313-test-instrumentation-sqlite3 -- -ra + + py314-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-sqlite3 -- -ra + + pypy3-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra + + py39-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-wsgi -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index 84909806377..960662b33c9 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -32,63 +32,6 @@ env: jobs: - py314-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-sqlite3 -- -ra - - pypy3-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra - - py39-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra - py310-test-instrumentation-wsgi_ubuntu-latest: name: instrumentation-wsgi 3.10 Ubuntu runs-on: ubuntu-latest @@ -4781,3 +4724,60 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra + + pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra + + py39-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-processor-baggage -- -ra + + py310-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-processor-baggage -- -ra diff --git a/.github/workflows/test_3.yml b/.github/workflows/test_3.yml index 933ffafa111..24625aa601a 100644 --- a/.github/workflows/test_3.yml +++ b/.github/workflows/test_3.yml @@ -32,63 +32,6 @@ env: jobs: - pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra - - py39-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra - - py310-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-processor-baggage -- -ra - py311-test-processor-baggage_ubuntu-latest: name: processor-baggage 3.11 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b3257fce7e..041d0a1233a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix intermittent `Core Contrib Test` CI failures caused by GitHub git CDN SHA propagation lag by installing core packages from the already-checked-out local copy instead of a second git clone ([#4305](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4305)) +### Breaking changes + +- `opentelemetry-instrumentation-boto`: Remove instrumentation + ([#4303](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4303)) + ## Version 1.40.0/0.61b0 (2026-03-04) ### Added diff --git a/docs-requirements.txt b/docs-requirements.txt index 99c7327c178..04c5e2eb62b 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -22,7 +22,6 @@ aiokafka~=0.11.0 aiopg>=0.13.0,<1.3.0 asyncpg>=0.12.0 asyncclick~=8.0 -boto~=2.0 botocore~=1.0 boto3~=1.0 cassandra-driver~=3.25 diff --git a/docs/instrumentation/boto/boto.rst b/docs/instrumentation/boto/boto.rst deleted file mode 100644 index c438c2466ca..00000000000 --- a/docs/instrumentation/boto/boto.rst +++ /dev/null @@ -1,7 +0,0 @@ -OpenTelemetry Boto Instrumentation -================================== - -.. automodule:: opentelemetry.instrumentation.boto - :members: - :undoc-members: - :show-inheritance: diff --git a/eachdist.ini b/eachdist.ini index 56c09f4361c..59467a8aedf 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -52,12 +52,9 @@ packages= opentelemetry-propagator-aws-xray opentelemetry-resource-detector-azure opentelemetry-sdk-extension-aws -<<<<<<< basic-http-opamp-client -======= opentelemetry-propagator-aws-xray opentelemetry-instrumentation-anthropic opentelemetry-instrumentation-claude-agent-sdk ->>>>>>> main opentelemetry-instrumentation-google-genai opentelemetry-instrumentation-vertexai opentelemetry-instrumentation-openai-v2 diff --git a/instrumentation/README.md b/instrumentation/README.md index d8b4b7216f1..e9a727d29b7 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -11,7 +11,6 @@ | [opentelemetry-instrumentation-asyncio](./opentelemetry-instrumentation-asyncio) | asyncio | No | development | [opentelemetry-instrumentation-asyncpg](./opentelemetry-instrumentation-asyncpg) | asyncpg >= 0.12.0 | No | development | [opentelemetry-instrumentation-aws-lambda](./opentelemetry-instrumentation-aws-lambda) | aws_lambda | No | development -| [opentelemetry-instrumentation-boto](./opentelemetry-instrumentation-boto) | boto~=2.0 | No | development | [opentelemetry-instrumentation-boto3sqs](./opentelemetry-instrumentation-boto3sqs) | boto3 ~= 1.0 | No | development | [opentelemetry-instrumentation-botocore](./opentelemetry-instrumentation-botocore) | botocore ~= 1.0 | No | development | [opentelemetry-instrumentation-cassandra](./opentelemetry-instrumentation-cassandra) | cassandra-driver ~= 3.25,scylla-driver ~= 3.25 | No | development diff --git a/instrumentation/opentelemetry-instrumentation-boto/LICENSE b/instrumentation/opentelemetry-instrumentation-boto/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/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/instrumentation/opentelemetry-instrumentation-boto/README.rst b/instrumentation/opentelemetry-instrumentation-boto/README.rst deleted file mode 100644 index 86472c1bc60..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/README.rst +++ /dev/null @@ -1,24 +0,0 @@ -OpenTelemetry Boto Tracing -========================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-boto.svg - :target: https://pypi.org/project/opentelemetry-instrumentation-boto/ - -This library allows tracing requests made by the Boto library. - -Installation ------------- - -:: - - pip install opentelemetry-instrumentation-boto - - -References ----------- - -* `OpenTelemetry Boto Tracing `_ -* `OpenTelemetry Project `_ -* `OpenTelemetry Python Examples `_ diff --git a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml deleted file mode 100644 index c3c20bf8ea2..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/pyproject.toml +++ /dev/null @@ -1,55 +0,0 @@ -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[project] -name = "opentelemetry-instrumentation-boto" -dynamic = ["version"] -description = "OpenTelemetry Boto instrumentation" -readme = "README.rst" -license = "Apache-2.0" -requires-python = ">=3.9" -authors = [ - { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, -] -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: 3.14", -] -dependencies = [ - "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", -] - -[project.optional-dependencies] -instruments = [ - "boto~=2.0", -] - -[project.entry-points.opentelemetry_instrumentor] -boto = "opentelemetry.instrumentation.boto:BotoInstrumentor" - -[project.urls] -Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-boto" -Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" - -[tool.hatch.version] -path = "src/opentelemetry/instrumentation/boto/version.py" - -[tool.hatch.build.targets.sdist] -include = [ - "/src", - "/tests", -] - -[tool.hatch.build.targets.wheel] -packages = ["src/opentelemetry"] diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py deleted file mode 100644 index ca0218fe9f4..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py +++ /dev/null @@ -1,252 +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. -""" -Instrument `Boto`_ to trace service requests. - -There are two options for instrumenting code. The first option is to use the -``opentelemetry-instrument`` executable which will automatically -instrument your Boto client. The second is to programmatically enable -instrumentation via the following code: - -.. _boto: https://pypi.org/project/boto/ - -Usage ------ - -.. code:: python - - from opentelemetry.instrumentation.boto import BotoInstrumentor - import boto - - - # Instrument Boto - BotoInstrumentor().instrument() - - # This will create a span with Boto-specific attributes - ec2 = boto.ec2.connect_to_region("us-west-2") - ec2.get_all_instances() - -API ---- -""" - -import logging -from inspect import currentframe -from typing import Collection - -from boto.connection import AWSAuthConnection, AWSQueryConnection -from wrapt import wrap_function_wrapper - -from opentelemetry.instrumentation.boto.package import _instruments -from opentelemetry.instrumentation.boto.version import __version__ -from opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.instrumentation.utils import unwrap -from opentelemetry.semconv._incubating.attributes.http_attributes import ( - HTTP_METHOD, - HTTP_STATUS_CODE, -) -from opentelemetry.trace import SpanKind, get_tracer - -logger = logging.getLogger(__name__) - -SERVICE_PARAMS_BLOCK_LIST = {"s3": ["params.Body"]} - - -def _get_instance_region_name(instance): - region = getattr(instance, "region", None) - - if not region: - return None - if isinstance(region, str): - return region.split(":")[1] - return region.name - - -class BotoInstrumentor(BaseInstrumentor): - """A instrumentor for Boto - - See `BaseInstrumentor` - """ - - def __init__(self): - super().__init__() - self._original_boto = None - - def instrumentation_dependencies(self) -> Collection[str]: - return _instruments - - def _instrument(self, **kwargs): - # AWSQueryConnection and AWSAuthConnection are two different classes - # called by different services for connection. - # For example EC2 uses AWSQueryConnection and S3 uses - # AWSAuthConnection - - # pylint: disable=attribute-defined-outside-init - self._tracer = get_tracer( - __name__, - __version__, - kwargs.get("tracer_provider"), - schema_url="https://opentelemetry.io/schemas/1.11.0", - ) - - wrap_function_wrapper( - "boto.connection", - "AWSQueryConnection.make_request", - self._patched_query_request, - ) - wrap_function_wrapper( - "boto.connection", - "AWSAuthConnection.make_request", - self._patched_auth_request, - ) - - def _uninstrument(self, **kwargs): - unwrap(AWSQueryConnection, "make_request") - unwrap(AWSAuthConnection, "make_request") - - def _common_request( # pylint: disable=too-many-locals - self, - args_name, - traced_args, - operation_name, - original_func, - instance, - args, - kwargs, - ): - endpoint_name = getattr(instance, "host").split(".")[0] - - with self._tracer.start_as_current_span( - f"{endpoint_name}.command", - kind=SpanKind.CONSUMER, - ) as span: - span.set_attribute("endpoint", endpoint_name) - if args: - http_method = args[0] - span.set_attribute("http_method", http_method.lower()) - - # Original func returns a boto.connection.HTTPResponse object - result = original_func(*args, **kwargs) - - if span.is_recording(): - add_span_arg_tags( - span, - endpoint_name, - args, - args_name, - traced_args, - ) - - # Obtaining region name - region_name = _get_instance_region_name(instance) - - meta = { - "aws.agent": "boto", - "aws.operation": operation_name, - } - if region_name: - meta["aws.region"] = region_name - - for key, value in meta.items(): - span.set_attribute(key, value) - - span.set_attribute(HTTP_STATUS_CODE, getattr(result, "status")) - span.set_attribute(HTTP_METHOD, getattr(result, "_method")) - - return result - - def _patched_query_request(self, original_func, instance, args, kwargs): - return self._common_request( - ("operation_name", "params", "path", "verb"), - ["operation_name", "params", "path"], - args[0] if args else None, - original_func, - instance, - args, - kwargs, - ) - - def _patched_auth_request(self, original_func, instance, args, kwargs): - frame = currentframe().f_back - operation_name = None - while frame: - if frame.f_code.co_name == "make_request": - operation_name = frame.f_back.f_code.co_name - break - frame = frame.f_back - - return self._common_request( - ( - "method", - "path", - "headers", - "data", - "host", - "auth_path", - "sender", - ), - ["path", "data", "host"], - operation_name, - original_func, - instance, - args, - kwargs, - ) - - -def flatten_dict(dict_, sep=".", prefix=""): - """ - Returns a normalized dict of depth 1 with keys in order of embedding - """ - # NOTE: This should probably be in `opentelemetry.instrumentation.utils`. - # adapted from https://stackoverflow.com/a/19647596 - return ( - { - prefix + sep + k if prefix else k: v - for kk, vv in dict_.items() - for k, v in flatten_dict(vv, sep, kk).items() - } - if isinstance(dict_, dict) - else {prefix: dict_} - ) - - -def add_span_arg_tags(span, aws_service, args, args_names, args_traced): - def truncate_arg_value(value, max_len=1024): - """Truncate values which are bytes and greater than `max_len`. - Useful for parameters like "Body" in `put_object` operations. - """ - if isinstance(value, bytes) and len(value) > max_len: - return b"..." - - return value - - if not span.is_recording(): - return - - # Do not trace `Key Management Service` or `Secure Token Service` API calls - # over concerns of security leaks. - if aws_service not in {"kms", "sts"}: - tags = { - name: value - for (name, value) in zip(args_names, args) - if name in args_traced - } - tags = flatten_dict(tags) - - for param_key, value in tags.items(): - if param_key in SERVICE_PARAMS_BLOCK_LIST.get(aws_service, {}): - continue - - span.set_attribute(param_key, truncate_arg_value(value)) diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/package.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/package.py deleted file mode 100644 index c967086b1f2..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/package.py +++ /dev/null @@ -1,16 +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. - - -_instruments = ("boto~=2.0",) diff --git a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py b/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py deleted file mode 100644 index ed89ddd1cc5..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/version.py +++ /dev/null @@ -1,15 +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. - -__version__ = "0.62b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt deleted file mode 100644 index d73e7447ed7..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt +++ /dev/null @@ -1,37 +0,0 @@ -asgiref==3.8.1 -boto==2.49.0 -boto3==1.34.44 -botocore==1.34.44 -certifi==2024.7.4 -cffi==1.17.0 -charset-normalizer==3.3.2 -cryptography==43.0.1 -Deprecated==1.2.14 -docker==7.0.0 -idna==3.7 -iniconfig==2.0.0 -Jinja2==3.1.6 -jmespath==1.0.1 -MarkupSafe==2.1.5 -moto==2.3.2 -packaging==24.0 -pluggy==1.5.0 -py-cpuinfo==9.0.0 -pycparser==2.21 -pytest==7.4.4 -python-dateutil==2.8.2 -pytz==2024.1 -PyYAML==6.0.1 -requests==2.32.3 -responses==0.25.0 -s3transfer==0.10.0 -six==1.16.0 -tomli==2.0.1 -typing_extensions==4.12.2 -urllib3==1.26.19 -Werkzeug==2.3.8 -wrapt==1.16.0 -xmltodict==0.13.0 -zipp==3.19.2 --e opentelemetry-instrumentation --e instrumentation/opentelemetry-instrumentation-boto diff --git a/instrumentation/opentelemetry-instrumentation-boto/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-boto/tests/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/instrumentation/opentelemetry-instrumentation-boto/tests/conftest.py b/instrumentation/opentelemetry-instrumentation-boto/tests/conftest.py deleted file mode 100644 index 884c6753c16..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/tests/conftest.py +++ /dev/null @@ -1,31 +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 os import environ - - -def pytest_sessionstart(session): - # pylint: disable=unused-argument - environ["AWS_ACCESS_KEY_ID"] = "testing" - environ["AWS_SECRET_ACCESS_KEY"] = "testing" - environ["AWS_SECURITY_TOKEN"] = "testing" - environ["AWS_SESSION_TOKEN"] = "testing" - - -def pytest_sessionfinish(session): - # pylint: disable=unused-argument - environ.pop("AWS_ACCESS_KEY_ID") - environ.pop("AWS_SECRET_ACCESS_KEY") - environ.pop("AWS_SECURITY_TOKEN") - environ.pop("AWS_SESSION_TOKEN") diff --git a/instrumentation/opentelemetry-instrumentation-boto/tests/test_boto_instrumentation.py b/instrumentation/opentelemetry-instrumentation-boto/tests/test_boto_instrumentation.py deleted file mode 100644 index 89684d4a052..00000000000 --- a/instrumentation/opentelemetry-instrumentation-boto/tests/test_boto_instrumentation.py +++ /dev/null @@ -1,285 +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 unittest import skipUnless -from unittest.mock import Mock, patch - -import boto.awslambda -import boto.ec2 -import boto.elasticache -import boto.s3 -import boto.sts -from moto import ( # pylint: disable=import-error - mock_ec2_deprecated, - mock_lambda_deprecated, - mock_s3_deprecated, - mock_sts_deprecated, -) - -from opentelemetry.instrumentation.boto import BotoInstrumentor -from opentelemetry.semconv._incubating.attributes.http_attributes import ( - HTTP_METHOD, - HTTP_STATUS_CODE, -) -from opentelemetry.test.test_base import TestBase - - -def assert_span_http_status_code(span, code): - """Assert on the span's 'http.status_code' tag""" - tag = span.attributes[HTTP_STATUS_CODE] - assert tag == code, f"{tag} != {code}" - - -class TestBotoInstrumentor(TestBase): - """Botocore integration testsuite""" - - def setUp(self): - super().setUp() - BotoInstrumentor().instrument() - - def tearDown(self): - BotoInstrumentor().uninstrument() - - @mock_ec2_deprecated - def test_ec2_client(self): - ec2 = boto.ec2.connect_to_region("us-west-2") - - ec2.get_all_instances() - - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 1) - span = spans[0] - self.assertEqual(span.attributes["aws.operation"], "DescribeInstances") - assert_span_http_status_code(span, 200) - self.assertEqual(span.attributes[HTTP_METHOD], "POST") - self.assertEqual(span.attributes["aws.region"], "us-west-2") - - # Create an instance - ec2.run_instances(21) - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 2) - span = spans[1] - self.assertEqual(span.attributes["aws.operation"], "RunInstances") - assert_span_http_status_code(span, 200) - self.assertEqual(span.attributes["endpoint"], "ec2") - self.assertEqual(span.attributes["http_method"], "runinstances") - self.assertEqual(span.attributes[HTTP_METHOD], "POST") - self.assertEqual(span.attributes["aws.region"], "us-west-2") - self.assertEqual(span.name, "ec2.command") - - @mock_ec2_deprecated - def test_not_recording(self): - mock_tracer = Mock() - mock_span = Mock() - mock_span.is_recording.return_value = False - mock_tracer.start_span.return_value = mock_span - with patch("opentelemetry.trace.get_tracer") as tracer: - tracer.return_value = mock_tracer - ec2 = boto.ec2.connect_to_region("us-west-2") - ec2.get_all_instances() - self.assertFalse(mock_span.is_recording()) - self.assertTrue(mock_span.is_recording.called) - self.assertFalse(mock_span.set_attribute.called) - self.assertFalse(mock_span.set_status.called) - - @mock_ec2_deprecated - def test_analytics_enabled_with_rate(self): - ec2 = boto.ec2.connect_to_region("us-west-2") - - ec2.get_all_instances() - - spans = self.memory_exporter.get_finished_spans() - assert spans - - @mock_ec2_deprecated - def test_analytics_enabled_without_rate(self): - ec2 = boto.ec2.connect_to_region("us-west-2") - - ec2.get_all_instances() - - spans = self.memory_exporter.get_finished_spans() - assert spans - - @mock_s3_deprecated - def test_s3_client(self): - s3 = boto.s3.connect_to_region("us-east-1") - - s3.get_all_buckets() - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 1) - span = spans[0] - assert_span_http_status_code(span, 200) - self.assertEqual(span.attributes[HTTP_METHOD], "GET") - self.assertEqual(span.attributes["aws.operation"], "get_all_buckets") - - # Create a bucket command - s3.create_bucket("cheese") - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 2) - span = spans[1] - assert_span_http_status_code(span, 200) - self.assertEqual(span.attributes[HTTP_METHOD], "PUT") - self.assertEqual(span.attributes["path"], "/") - self.assertEqual(span.attributes["aws.operation"], "create_bucket") - - # Get the created bucket - s3.get_bucket("cheese") - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 3) - span = spans[2] - assert_span_http_status_code(span, 200) - self.assertEqual(span.attributes["endpoint"], "s3") - self.assertEqual(span.attributes["http_method"], "head") - self.assertEqual(span.attributes[HTTP_METHOD], "HEAD") - self.assertEqual(span.attributes["aws.operation"], "head_bucket") - self.assertEqual(span.name, "s3.command") - - # Checking for resource in case of error - try: - s3.get_bucket("big_bucket") - except Exception: # pylint: disable=broad-except - spans = self.memory_exporter.get_finished_spans() - assert spans - span = spans[2] - self.assertEqual(spans[2].attributes["endpoint"], "s3") - self.assertEqual(spans[2].attributes["http_method"], "head") - - @mock_s3_deprecated - def test_s3_put(self): - s3 = boto.s3.connect_to_region("us-east-1") - s3.create_bucket("mybucket") - bucket = s3.get_bucket("mybucket") - key = boto.s3.key.Key(bucket) - key.key = "foo" - key.set_contents_from_string("bar") - - spans = self.memory_exporter.get_finished_spans() - assert spans - # create bucket - self.assertEqual(len(spans), 3) - self.assertEqual(spans[0].attributes["aws.operation"], "create_bucket") - assert_span_http_status_code(spans[0], 200) - self.assertEqual(spans[0].attributes["endpoint"], "s3") - self.assertEqual(spans[0].attributes["http_method"], "put") - # get bucket - self.assertEqual(spans[1].attributes["aws.operation"], "head_bucket") - self.assertEqual(spans[1].attributes["endpoint"], "s3") - self.assertEqual(spans[1].attributes["http_method"], "head") - # put object - self.assertEqual( - spans[2].attributes["aws.operation"], "_send_file_internal" - ) - self.assertEqual(spans[2].attributes["endpoint"], "s3") - self.assertEqual(spans[2].attributes["http_method"], "put") - - @mock_lambda_deprecated - def test_unpatch(self): - lamb = boto.awslambda.connect_to_region("us-east-2") - - BotoInstrumentor().uninstrument() - - # multiple calls - lamb.list_functions() - spans = self.memory_exporter.get_finished_spans() - assert not spans, spans - - @mock_s3_deprecated - def test_double_patch(self): - s3 = boto.s3.connect_to_region("us-east-1") - - BotoInstrumentor().instrument() - BotoInstrumentor().instrument() - - # Get the created bucket - s3.create_bucket("cheese") - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 1) - - @mock_s3_deprecated - def test_uninstrument(self): - s3 = boto.s3.connect_to_region("us-east-1") - # Get the created bucket - s3.create_bucket("cheese") - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 1) - - self.memory_exporter.clear() - BotoInstrumentor().uninstrument() - - s3.get_bucket("cheese") - spans = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans), 0) - - @mock_lambda_deprecated - def test_lambda_client(self): - lamb = boto.awslambda.connect_to_region("us-east-2") - - # multiple calls - lamb.list_functions() - lamb.list_functions() - - spans = self.memory_exporter.get_finished_spans() - assert spans - self.assertEqual(len(spans), 2) - span = spans[0] - assert_span_http_status_code(span, 200) - self.assertEqual(span.attributes["endpoint"], "lambda") - self.assertEqual(span.attributes["http_method"], "get") - self.assertEqual(span.attributes[HTTP_METHOD], "GET") - self.assertEqual(span.attributes["aws.region"], "us-east-2") - self.assertEqual(span.attributes["aws.operation"], "list_functions") - - @mock_sts_deprecated - def test_sts_client(self): - sts = boto.sts.connect_to_region("us-west-2") - - sts.get_federation_token(12, duration=10) - - spans = self.memory_exporter.get_finished_spans() - assert spans - span = spans[0] - self.assertEqual(span.attributes["endpoint"], "sts") - self.assertEqual(span.attributes["http_method"], "getfederationtoken") - self.assertEqual(span.attributes["aws.region"], "us-west-2") - self.assertEqual( - span.attributes["aws.operation"], "GetFederationToken" - ) - - # checking for protection on sts against security leak - self.assertTrue("args.path" not in span.attributes.keys()) - - @skipUnless( - False, - ( - "Test to reproduce the case where args sent to patched function " - "are None, can't be mocked: needs AWS credentials" - ), - ) - def test_elasticache_client(self): - elasticache = boto.elasticache.connect_to_region("us-west-2") - - elasticache.describe_cache_clusters() - - spans = self.memory_exporter.get_finished_spans() - assert spans - span = spans[0] - self.assertEqual(span.attributes["endpoint"], "elasticcache") - self.assertEqual(span.attributes["aws.region"], "us-west-2") diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 0b4a0c8398b..04cce7f6e1d 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -40,7 +40,6 @@ dependencies = [ "opentelemetry-instrumentation-asyncio==0.62b0.dev", "opentelemetry-instrumentation-asyncpg==0.62b0.dev", "opentelemetry-instrumentation-aws-lambda==0.62b0.dev", - "opentelemetry-instrumentation-boto==0.62b0.dev", "opentelemetry-instrumentation-boto3sqs==0.62b0.dev", "opentelemetry-instrumentation-botocore==0.62b0.dev", "opentelemetry-instrumentation-cassandra==0.62b0.dev", diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 3aac3453fe2..2a0d42507a4 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -56,10 +56,6 @@ "library": "asyncpg >= 0.12.0", "instrumentation": "opentelemetry-instrumentation-asyncpg==0.62b0.dev", }, - { - "library": "boto~=2.0", - "instrumentation": "opentelemetry-instrumentation-boto==0.62b0.dev", - }, { "library": "boto3 ~= 1.0", "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.62b0.dev", diff --git a/pyproject.toml b/pyproject.toml index 7e6b2c85258..736f1c3edf0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,6 @@ dependencies = [ "opentelemetry-instrumentation-asyncio", "opentelemetry-instrumentation-asyncpg[instruments]", "opentelemetry-instrumentation-aws-lambda[instruments]", - "opentelemetry-instrumentation-boto[instruments]", "opentelemetry-instrumentation-boto3sqs[instruments]", "opentelemetry-instrumentation-botocore[instruments]", "opentelemetry-instrumentation-cassandra[instruments]", @@ -93,7 +92,6 @@ opentelemetry-instrumentation-asgi = { workspace = true } opentelemetry-instrumentation-asyncio = { workspace = true } opentelemetry-instrumentation-asyncpg = { workspace = true } opentelemetry-instrumentation-aws-lambda = { workspace = true } -opentelemetry-instrumentation-boto = { workspace = true } opentelemetry-instrumentation-boto3sqs = { workspace = true } opentelemetry-instrumentation-botocore = { workspace = true } opentelemetry-instrumentation-cassandra = { workspace = true } diff --git a/tox.ini b/tox.ini index 062dbfc74d1..8c5ff3aca9e 100644 --- a/tox.ini +++ b/tox.ini @@ -119,12 +119,6 @@ envlist = pypy3-test-instrumentation-dbapi-wrapt2 lint-instrumentation-dbapi - ; opentelemetry-instrumentation-boto - py3{9,10,11}-test-instrumentation-boto - ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 - ; pypy3-test-instrumentation-boto - lint-instrumentation-boto - ; opentelemetry-instrumentation-asyncclick py3{9,10,11,12,13,14}-test-instrumentation-asyncclick pypy3-test-instrumentation-asyncclick @@ -572,9 +566,6 @@ deps = aws-lambda: {[testenv]test_deps} aws-lambda: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt - boto: {[testenv]test_deps} - boto: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-boto/test-requirements.txt - boto3sqs: {[testenv]test_deps} boto3sqs: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -847,9 +838,6 @@ commands = test-instrumentation-aws-lambda: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-aws-lambda/tests {posargs} lint-instrumentation-aws-lambda: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-aws-lambda" - test-instrumentation-boto: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-boto/tests {posargs} - lint-instrumentation-boto: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-boto" - test-instrumentation-botocore: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/tests {posargs} lint-instrumentation-botocore: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-botocore" diff --git a/uv.lock b/uv.lock index 404d798da1e..ad3f6483c78 100644 --- a/uv.lock +++ b/uv.lock @@ -26,7 +26,6 @@ members = [ "opentelemetry-instrumentation-asyncio", "opentelemetry-instrumentation-asyncpg", "opentelemetry-instrumentation-aws-lambda", - "opentelemetry-instrumentation-boto", "opentelemetry-instrumentation-boto3sqs", "opentelemetry-instrumentation-botocore", "opentelemetry-instrumentation-cassandra", @@ -530,15 +529,6 @@ 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 = "boto" -version = "2.49.0" -source = { registry = "https://pypi.org/simple/" } -sdist = { url = "https://files.pythonhosted.org/packages/c8/af/54a920ff4255664f5d238b5aebd8eedf7a07c7a5e71e27afcfe840b82f51/boto-2.49.0.tar.gz", hash = "sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a", size = 1478498, upload-time = "2018-07-11T20:58:58.057Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/23/10/c0b78c27298029e4454a472a1919bde20cb182dab1662cec7f2ca1dcc523/boto-2.49.0-py2.py3-none-any.whl", hash = "sha256:147758d41ae7240dc989f0039f27da8ca0d53734be0eb869ef16e3adcfa462e8", size = 1359202, upload-time = "2018-07-11T20:58:55.711Z" }, -] - [[package]] name = "boto3" version = "1.42.53" @@ -2976,29 +2966,6 @@ requires-dist = [ ] provides-extras = ["instruments"] -[[package]] -name = "opentelemetry-instrumentation-boto" -source = { editable = "instrumentation/opentelemetry-instrumentation-boto" } -dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-instrumentation" }, - { name = "opentelemetry-semantic-conventions" }, -] - -[package.optional-dependencies] -instruments = [ - { name = "boto" }, -] - -[package.metadata] -requires-dist = [ - { name = "boto", marker = "extra == 'instruments'", specifier = "~=2.0" }, - { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, - { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, - { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, -] -provides-extras = ["instruments"] - [[package]] name = "opentelemetry-instrumentation-boto3sqs" source = { editable = "instrumentation/opentelemetry-instrumentation-boto3sqs" } @@ -4176,7 +4143,6 @@ dependencies = [ { name = "opentelemetry-instrumentation-asyncio" }, { name = "opentelemetry-instrumentation-asyncpg", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-aws-lambda" }, - { name = "opentelemetry-instrumentation-boto", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-boto3sqs", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-botocore", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-cassandra" }, @@ -4248,7 +4214,6 @@ requires-dist = [ { name = "opentelemetry-instrumentation-asyncio", editable = "instrumentation/opentelemetry-instrumentation-asyncio" }, { name = "opentelemetry-instrumentation-asyncpg", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-asyncpg" }, { name = "opentelemetry-instrumentation-aws-lambda", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-aws-lambda" }, - { name = "opentelemetry-instrumentation-boto", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-boto" }, { name = "opentelemetry-instrumentation-boto3sqs", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-boto3sqs" }, { name = "opentelemetry-instrumentation-botocore", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-botocore" }, { name = "opentelemetry-instrumentation-cassandra", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-cassandra" }, From 6fae4c1187c4c752b8ff73613cf7ac6dca3b25f5 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 12 Mar 2026 10:18:50 +0100 Subject: [PATCH 13/78] tests requirements: Bump pluggy to 1.6.0 (#4319) To silence some Python 3.14 warnings. --- .../test-requirements.txt | 2 +- .../opentelemetry-exporter-richconsole/test-requirements.txt | 2 +- .../tests/requirements.latest.txt | 2 +- .../tests/requirements.oldest.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-aiopg/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-asgi/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-asyncio/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-asyncpg/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-scylla.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../opentelemetry-instrumentation-click/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-dbapi/test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-4.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-0.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-1.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-2.txt | 2 +- .../opentelemetry-instrumentation-flask/test-requirements-3.txt | 2 +- .../opentelemetry-instrumentation-grpc/test-requirements-0.txt | 2 +- .../opentelemetry-instrumentation-grpc/test-requirements-1.txt | 2 +- .../opentelemetry-instrumentation-httpx/test-requirements-0.txt | 2 +- .../opentelemetry-instrumentation-httpx/test-requirements-1.txt | 2 +- .../opentelemetry-instrumentation-jinja2/test-requirements.txt | 2 +- .../test-requirements-ng.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-logging/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-mysql/test-requirements-0.txt | 2 +- .../opentelemetry-instrumentation-mysql/test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-pika/test-requirements-0.txt | 2 +- .../opentelemetry-instrumentation-pika/test-requirements-1.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-binary.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../test-requirements-3.txt | 2 +- .../test-requirements-4.txt | 2 +- .../opentelemetry-instrumentation-pymongo/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-pymssql/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-pymysql/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-pyramid/test-requirements.txt | 2 +- .../opentelemetry-instrumentation-redis/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements-2.txt | 2 +- .../opentelemetry-instrumentation-sqlite3/test-requirements.txt | 2 +- .../test-requirements.latest.txt | 2 +- .../test-requirements.oldest.txt | 2 +- .../test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-tornado/test-requirements.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-instrumentation-urllib/test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../opentelemetry-instrumentation-wsgi/test-requirements.txt | 2 +- opamp/opentelemetry-opamp-client/test-requirements.lowest.txt | 2 +- opentelemetry-distro/test-requirements.txt | 2 +- opentelemetry-instrumentation/test-requirements.txt | 2 +- .../opentelemetry-propagator-aws-xray/test-requirements-0.txt | 2 +- .../opentelemetry-propagator-aws-xray/test-requirements-1.txt | 2 +- .../opentelemetry-propagator-ot-trace/test-requirements.txt | 2 +- .../test-requirements-0.txt | 2 +- .../test-requirements-1.txt | 2 +- .../test-requirements.txt | 2 +- .../opentelemetry-sdk-extension-aws/test-requirements-0.txt | 2 +- .../opentelemetry-sdk-extension-aws/test-requirements-1.txt | 2 +- util/opentelemetry-util-http/test-requirements.txt | 2 +- 96 files changed, 96 insertions(+), 96 deletions(-) diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt index 129f0589a72..bb03ea12360 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/test-requirements.txt @@ -6,7 +6,7 @@ Deprecated==1.2.14 idna==3.7 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 protobuf==6.33.5 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt index 40d37f1d66a..d00e32aa9e5 100644 --- a/exporter/opentelemetry-exporter-richconsole/test-requirements.txt +++ b/exporter/opentelemetry-exporter-richconsole/test-requirements.txt @@ -5,7 +5,7 @@ iniconfig==2.0.0 markdown-it-py==3.0.0 mdurl==0.1.2 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 Pygments==2.17.2 pytest==7.4.4 diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.latest.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.latest.txt index 74005b7afbe..a818affa54d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.latest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.latest.txt @@ -61,7 +61,7 @@ importlib_metadata==8.5.0 iniconfig==2.0.0 multidict==6.1.0 packaging==24.2 -pluggy==1.5.0 +pluggy==1.6.0 propcache==0.2.0 proto-plus==1.25.0 protobuf==5.29.1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt index 7bfd62ff5fb..5b5c7e8f671 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt @@ -39,7 +39,7 @@ importlib-metadata==6.11.0 iniconfig==2.0.0 multidict==6.1.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 propcache==0.2.0 proto-plus==1.25.0 protobuf==5.29.1 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt index c2847c672c6..61110dde109 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-0.txt @@ -7,7 +7,7 @@ iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 pamqp==3.1.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt index 7c12b25ea44..f3d7fa41a8e 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-1.txt @@ -7,7 +7,7 @@ iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 pamqp==3.2.1 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt index 3a4c21b3f74..24e7c6cdaa7 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-2.txt @@ -7,7 +7,7 @@ iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 pamqp==3.2.1 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt index f5b8fdf3457..12f66a03087 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/test-requirements-3.txt @@ -7,7 +7,7 @@ iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 pamqp==3.3.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt index 55ddf646dcd..335548eb3ca 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -17,7 +17,7 @@ Jinja2==3.1.6 MarkupSafe==2.1.5 multidict==6.0.5 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 requests==2.32.3 diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt index d492daf3c65..cd3dee92a02 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/test-requirements.txt @@ -8,7 +8,7 @@ idna==3.7 iniconfig==2.0.0 multidict==6.0.5 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-aiohttp==1.0.5 diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt index 5c8b7448e0f..d40176d9f0c 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiopg/test-requirements.txt @@ -3,7 +3,7 @@ asgiref==3.8.1 async-timeout==4.0.3 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 psycopg2-binary==2.9.10 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt index 4b87261ffb5..b41ffa06c0d 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt index 4f1877dd432..203aeebb0ae 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncio/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-asyncio==0.23.5 diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt index 695688994f8..f0dd93d2685 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/test-requirements.txt @@ -3,7 +3,7 @@ async-timeout==4.0.3 asyncpg==0.30.0 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt index 75c3a56b62e..1cf679a579e 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt index 5adcd8ad150..7d86ce381cd 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/test-requirements.txt @@ -5,7 +5,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 jmespath==1.0.1 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 python-dateutil==2.8.2 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt index 4e084ef0cef..ba323fede98 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0.txt @@ -14,7 +14,7 @@ jmespath==1.0.1 MarkupSafe==2.1.5 moto==5.1.11 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pycparser==2.21 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt index 6cc42f92a78..361b6ce1bb7 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1.txt @@ -14,7 +14,7 @@ jmespath==1.0.1 MarkupSafe==2.1.5 moto==5.1.11 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pycparser==2.21 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements-scylla.txt b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements-scylla.txt index af661fb9b89..1411ba97fd7 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements-scylla.txt +++ b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements-scylla.txt @@ -5,7 +5,7 @@ Deprecated==1.2.14 geomet==0.2.1.post1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 python-snappy==0.7.3 diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt index b2e996f8400..1cdec8d3cd1 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt @@ -6,7 +6,7 @@ Deprecated==1.2.14 geomet==0.2.1.post1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 PyYAML==6.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt index 811d8056422..b5ee53c0a98 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt @@ -11,7 +11,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 kombu==5.3.5 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 prompt-toolkit==3.0.43 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt index 4d3afc74e4e..f57dd4b27b4 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -10,7 +10,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 kombu==5.3.5 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 prompt-toolkit==3.0.43 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt index f4d715a5e1c..a210b9cf556 100644 --- a/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt @@ -8,7 +8,7 @@ itsdangerous==2.1.2 Jinja2==3.1.6 MarkupSafe==2.1.2 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-asyncio==0.23.5 diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt index cf5791b3277..283b8525adf 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt @@ -3,7 +3,7 @@ confluent-kafka==2.13.2 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt index 249a7eab039..fa7a4f9580b 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements.txt @@ -1,7 +1,7 @@ asgiref==3.8.1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index f2375911d3b..de46d416348 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 Django==2.2.28 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytz==2024.1 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt index 12f934acd47..042598256c4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 Django==3.2.25 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytz==2024.1 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index 6d84c3db893..f7d12ec741e 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -4,7 +4,7 @@ Deprecated==1.2.14 Django==4.2.17 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 sqlparse==0.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt index e7c56b6050d..f917be97151 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 Django==5.2.11 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 sqlparse==0.5.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt index 7507078f848..e74be562464 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-0.txt @@ -4,7 +4,7 @@ elasticsearch==6.8.2 elasticsearch-dsl==6.4.0 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 python-dateutil==2.8.2 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt index fcd68f1c8eb..1398647ba7f 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-1.txt @@ -4,7 +4,7 @@ elasticsearch==7.17.9 elasticsearch-dsl==7.4.1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 python-dateutil==2.8.2 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt index 05af6f4d6c8..05446a82b67 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt @@ -5,7 +5,7 @@ elasticsearch-dsl==8.13.1 elastic-transport==8.13.0 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 python-dateutil==2.8.2 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt index 7b0ce1caf9b..d0d776451e5 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-0.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 falcon==1.4.1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 python-mimeparse==1.6.0 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt index 51f09a4c46d..22b0e6236c8 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-1.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 falcon==2.0.0 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt index cff1244cd0b..db9c60a0deb 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-2.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 falcon==3.1.1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt index 392a1ce385c..f8f238be202 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-3.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 falcon==3.1.3 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt index 0fd061b29a8..d1c7700cd8d 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt +++ b/instrumentation/opentelemetry-instrumentation-falcon/test-requirements-4.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 falcon==4.0.2 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt index 6bebbe414a7..f2c46ec39fc 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-0.txt @@ -7,7 +7,7 @@ itsdangerous==2.1.2 Jinja2==3.1.6 MarkupSafe==2.1.2 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt index c66c55df1d2..14b208cc981 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-1.txt @@ -7,7 +7,7 @@ itsdangerous==2.1.2 Jinja2==3.1.6 MarkupSafe==2.1.2 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt index 37364174194..f891cae043f 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-2.txt @@ -8,7 +8,7 @@ itsdangerous==2.1.2 Jinja2==3.1.6 MarkupSafe==2.1.2 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-3.txt index 0658a90bc86..e4c5a1e04b9 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-flask/test-requirements-3.txt @@ -8,7 +8,7 @@ itsdangerous>=2.2.0 Jinja2==3.1.6 MarkupSafe==2.1.2 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt index 9ab63cbe445..d255ca9a241 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-0.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 grpcio==1.62.0 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 protobuf==3.20.3 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt index bbb4e65ebd5..a639d0346b2 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-grpc/test-requirements-1.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 grpcio==1.75.1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 protobuf==3.20.3 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt index 9ecea68c2f2..725bc854723 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-0.txt @@ -8,7 +8,7 @@ httpx==0.18.2 idna==3.7 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 respx==0.17.1 diff --git a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt index 757bc643299..f0ca4be8b56 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-httpx/test-requirements-1.txt @@ -8,7 +8,7 @@ httpx==0.28.1 idna==3.7 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 respx==0.22.0 diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt index a4f8145b1e3..dbbd4b6d8e7 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-jinja2/test-requirements.txt @@ -4,7 +4,7 @@ iniconfig==2.0.0 Jinja2==3.1.6 MarkupSafe==2.0.1 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt index 83cef19c4fa..f989019867b 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements-ng.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 kafka-python-ng==2.2.2 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt index 87752e35429..14975e09c38 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/test-requirements.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 kafka-python==2.0.2 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt index 2512824c230..8d6098d6246 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt index 45fb95cb371..05d78ab5cab 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-0.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 mysql-connector-python==8.3.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt index 0ca8efb64cc..df8ed74d447 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-mysql/test-requirements-1.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 mysql-connector-python==9.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt index 0abcd23bd25..6cb821c22e4 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/test-requirements.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 mysqlclient==2.2.4 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt index fca0d25b881..697998ce839 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-0.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 iniconfig==2.0.0 packaging==24.0 pika==0.13.1 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt index 50fd870f9e6..645689b674f 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pika/test-requirements-1.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 iniconfig==2.0.0 packaging==24.0 pika==1.3.2 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt index a68ae0b7973..d28af01d88e 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt @@ -3,7 +3,7 @@ backports.zoneinfo==0.2.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 psycopg==3.1.18 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt index f18f4522a9b..c254e24834d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 psycopg==3.2.2 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt index 80fa036b998..f47e576ea1a 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements-binary.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 psycopg2-binary==2.9.10 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt index 305185e3628..8171330f1d7 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 psycopg2==2.9.10 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt index d1b214c5954..9379eb3087b 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-0.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pymemcache==1.3.5 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt index 64224bc7a5b..02515b7c0c7 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-1.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pymemcache==2.2.2 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt index d54b48ffeae..ccaf5fb9d15 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-2.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pymemcache==3.4.1 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt index 509bdda5a6c..37240eb242b 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-3.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pymemcache==3.4.2 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt index 93e1c041d51..c3b002f3c76 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/test-requirements-4.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pymemcache==4.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt index 1e8a49d67dc..962d918f3e3 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 dnspython==2.6.1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pymongo==4.6.3 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-pymssql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymssql/test-requirements.txt index 6b5972aafb3..ba53d09622b 100644 --- a/instrumentation/opentelemetry-instrumentation-pymssql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymssql/test-requirements.txt @@ -1,7 +1,7 @@ exceptiongroup==1.2.2 iniconfig==2.0.0 packaging==24.2 -pluggy==1.5.0 +pluggy==1.6.0 pymssql==2.3.12 pytest==7.4.4 tomli==2.2.1 diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt index 02018b0c5e7..759647c5811 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pymysql/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 PyMySQL==1.1.1 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt index 40438a9f88e..ea22666b4e8 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-pyramid/test-requirements.txt @@ -6,7 +6,7 @@ packaging==24.0 PasteDeploy==3.1.0 plaster==1.1.2 plaster-pastedeploy==1.0.1 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pyramid==2.0.2 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt index 6beac4a9cc5..627b13573c2 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-redis/test-requirements.txt @@ -4,7 +4,7 @@ Deprecated==1.2.14 fakeredis==2.23.3 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 redis==5.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt index bfa53ed1f8e..42ee69de5ab 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-remoulade/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 prometheus_client==0.20.0 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt index 0b8d7ada103..fb2a7a13c4e 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-requests/test-requirements.txt @@ -6,7 +6,7 @@ httpretty==1.1.4 idna==3.7 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 requests==2.32.3 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt index e3f87916c27..3bf49c244e2 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-0.txt @@ -3,7 +3,7 @@ cffi==1.17.0 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 SQLAlchemy==1.1.18 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt index 13ea334c4d4..cfecf5b91d8 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-1.txt @@ -4,7 +4,7 @@ Deprecated==1.2.14 greenlet==3.1.1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 SQLAlchemy==1.4.51 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt index 9193b5996a7..c628f928d66 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/test-requirements-2.txt @@ -5,7 +5,7 @@ greenlet==3.1.1 ; python_version < "3.10" greenlet==3.3.1 ; python_version >= "3.10" iniconfig==2.0.0 packaging==24.1 -pluggy==1.5.0 +pluggy==1.6.0 pytest==7.4.4 SQLAlchemy==2.0.36 typing_extensions==4.12.2 diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt index c6d1cb28e27..9e13e801d1a 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt index f28876044ef..e1057fed607 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt @@ -58,7 +58,7 @@ packaging==24.2 # via # opentelemetry-instrumentation # pytest -pluggy==1.5.0 +pluggy==1.6.0 # via pytest pytest==7.4.4 # via diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt index 5c367c4032d..99fd4853e98 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt @@ -56,7 +56,7 @@ packaging==24.0 # via # opentelemetry-instrumentation # pytest -pluggy==1.5.0 +pluggy==1.6.0 # via pytest pytest==7.4.4 # via diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt index d9d28bdcc4a..d30e775ee1b 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 psutil==7.0.0 py-cpuinfo==9.0.0 pytest==7.4.4 diff --git a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt index b40c591b6d4..681da528bc5 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-threading/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt index 07cd4106a58..8007e3a539c 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tornado/test-requirements.txt @@ -7,7 +7,7 @@ http_server_mock==1.7 idna==3.7 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 requests==2.32.3 diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt index 7d12ae86224..14d714bc5cc 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/test-requirements.txt @@ -5,7 +5,7 @@ Deprecated==1.2.14 iniconfig==2.0.0 iso8601==1.1.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pydantic==2.12.5 pydantic_core==2.41.5 diff --git a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt index 11fc6278951..44284f4e630 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib/test-requirements.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 httpretty==1.1.4 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt index d85ac17f4fd..f2f654f42a0 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-0.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 httpretty==1.1.4 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt index 14da384548c..693b6d6db58 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt +++ b/instrumentation/opentelemetry-instrumentation-urllib3/test-requirements-1.txt @@ -3,7 +3,7 @@ Deprecated==1.2.14 httpretty==1.1.4 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt index 433d9e32018..2aba56695dc 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-wsgi/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt b/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt index 914aae89556..2ab1d9826eb 100644 --- a/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt +++ b/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt @@ -28,7 +28,7 @@ packaging==24.0 # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest -pluggy==1.5.0 +pluggy==1.6.0 # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest diff --git a/opentelemetry-distro/test-requirements.txt b/opentelemetry-distro/test-requirements.txt index dba17daec3e..75e0e99298a 100644 --- a/opentelemetry-distro/test-requirements.txt +++ b/opentelemetry-distro/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/opentelemetry-instrumentation/test-requirements.txt b/opentelemetry-instrumentation/test-requirements.txt index d8088387a24..a05165dbbbe 100644 --- a/opentelemetry-instrumentation/test-requirements.txt +++ b/opentelemetry-instrumentation/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 gevent==25.5.1 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt index 9880271676e..f33b41e46e9 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements-0.txt @@ -5,7 +5,7 @@ Deprecated==1.2.14 idna==3.7 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 diff --git a/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt b/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt index 679800462e2..b3daf5cfca4 100644 --- a/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt +++ b/propagator/opentelemetry-propagator-aws-xray/test-requirements-1.txt @@ -5,7 +5,7 @@ Deprecated==1.2.14 idna==3.7 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 diff --git a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt index 379c534e26b..97b8f51755a 100644 --- a/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt +++ b/propagator/opentelemetry-propagator-ot-trace/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt b/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt index e694db3b529..792cae94656 100644 --- a/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt +++ b/resource/opentelemetry-resource-detector-azure/test-requirements-0.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 typing_extensions==4.12.2 diff --git a/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt b/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt index a2344e2871f..5d78dff62bb 100644 --- a/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt +++ b/resource/opentelemetry-resource-detector-azure/test-requirements-1.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 typing_extensions==4.12.2 diff --git a/resource/opentelemetry-resource-detector-containerid/test-requirements.txt b/resource/opentelemetry-resource-detector-containerid/test-requirements.txt index fbad04cd331..db0cc5ab585 100644 --- a/resource/opentelemetry-resource-detector-containerid/test-requirements.txt +++ b/resource/opentelemetry-resource-detector-containerid/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt index e5986b6adad..53757d63647 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-0.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt index 997a3733838..b702824d72d 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt +++ b/sdk-extension/opentelemetry-sdk-extension-aws/test-requirements-1.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 pytest-benchmark==4.0.0 diff --git a/util/opentelemetry-util-http/test-requirements.txt b/util/opentelemetry-util-http/test-requirements.txt index ea2448bab9c..01a7bff69a0 100644 --- a/util/opentelemetry-util-http/test-requirements.txt +++ b/util/opentelemetry-util-http/test-requirements.txt @@ -2,7 +2,7 @@ asgiref==3.8.1 Deprecated==1.2.14 iniconfig==2.0.0 packaging==24.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 pytest==7.4.4 tomli==2.0.1 From 9e8ef976d0f1f6a786b1bd1a9dddd129a1ac7065 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 12 Mar 2026 02:42:03 -0700 Subject: [PATCH 14/78] GenAI utils: add schema_url to metrics (#4320) * add schema_url to metrics * changelog * review * simplify further * simplify further --------- Co-authored-by: Riccardo Magliocchetti --- util/opentelemetry-util-genai/CHANGELOG.md | 3 ++ .../src/opentelemetry/util/genai/handler.py | 9 ++-- .../tests/test_handler_metrics.py | 50 +++++++++++++++---- .../tests/test_utils.py | 25 +++++++++- 4 files changed, 74 insertions(+), 13 deletions(-) diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index f64092a697c..82f09188f90 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Populate schema_url on metrics + ([#4320](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4320)) + ## Version 0.3b0 (2026-02-20) - Add `gen_ai.tool_definitions` to completion hook ([#4181](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4181)) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py index 54e626deaa7..4e85799ea1e 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py @@ -100,20 +100,23 @@ def __init__( meter_provider: MeterProvider | None = None, logger_provider: LoggerProvider | None = None, ): + schema_url = Schemas.V1_37_0.value self._tracer = get_tracer( __name__, __version__, tracer_provider, - schema_url=Schemas.V1_37_0.value, + schema_url=schema_url, ) self._metrics_recorder: InvocationMetricsRecorder | None = None - meter = get_meter(__name__, meter_provider=meter_provider) + meter = get_meter( + __name__, meter_provider=meter_provider, schema_url=schema_url + ) self._metrics_recorder = InvocationMetricsRecorder(meter) self._logger = get_logger( __name__, __version__, logger_provider, - schema_url=Schemas.V1_37_0.value, + schema_url=schema_url, ) def _record_llm_metrics( diff --git a/util/opentelemetry-util-genai/tests/test_handler_metrics.py b/util/opentelemetry-util-genai/tests/test_handler_metrics.py index abfba3c7e67..6db12f0cd2c 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_metrics.py +++ b/util/opentelemetry-util-genai/tests/test_handler_metrics.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Dict, List +from typing import Any, Dict, List, Tuple from unittest import TestCase from unittest.mock import patch @@ -14,9 +14,12 @@ from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAI, ) +from opentelemetry.semconv.schemas import Schemas from opentelemetry.util.genai.handler import TelemetryHandler from opentelemetry.util.genai.types import Error, LLMInvocation +_DEFAULT_SCHEMA_URL = Schemas.V1_37_0.value + class TelemetryHandlerMetricsTest(TestCase): def setUp(self) -> None: @@ -49,7 +52,10 @@ def test_stop_llm_records_duration_and_tokens(self) -> None: ): handler.stop_llm(invocation) - metrics = self._harvest_metrics() + metrics, resource_metrics = self._harvest_metrics() + self._assert_metric_scope_schema_urls( + resource_metrics, _DEFAULT_SCHEMA_URL + ) self.assertIn("gen_ai.client.operation.duration", metrics) duration_points = metrics["gen_ai.client.operation.duration"] self.assertEqual(len(duration_points), 1) @@ -104,7 +110,10 @@ def test_stop_llm_records_duration_and_tokens_with_additional_attributes( invocation.attributes = {"should not be on metrics": "value"} handler.stop_llm(invocation) - metrics = self._harvest_metrics() + metrics, resource_metrics = self._harvest_metrics() + self._assert_metric_scope_schema_urls( + resource_metrics, _DEFAULT_SCHEMA_URL + ) self.assertIn("gen_ai.client.operation.duration", metrics) duration_points = metrics["gen_ai.client.operation.duration"] self.assertIn("gen_ai.client.token.usage", metrics) @@ -139,7 +148,10 @@ def test_fail_llm_records_error_and_available_tokens(self) -> None: ): handler.fail_llm(invocation, error) - metrics = self._harvest_metrics() + metrics, resource_metrics = self._harvest_metrics() + self._assert_metric_scope_schema_urls( + resource_metrics, _DEFAULT_SCHEMA_URL + ) self.assertIn("gen_ai.client.operation.duration", metrics) duration_points = metrics["gen_ai.client.operation.duration"] self.assertEqual(len(duration_points), 1) @@ -163,17 +175,37 @@ def test_fail_llm_records_error_and_available_tokens(self) -> None: ) self.assertAlmostEqual(token_point.sum, 11.0, places=3) - def _harvest_metrics(self) -> Dict[str, List[Any]]: + def _harvest_metrics( + self, + ) -> Tuple[Dict[str, List[Any]], List[Any]]: + """Returns (metrics_by_name, resource_metrics). + + metrics_by_name maps metric name to list of data points. + resource_metrics is the raw ResourceMetrics list for scope-level + assertions (e.g. schema_url). + """ try: self.meter_provider.force_flush() except Exception: # pylint: disable=broad-except - pass + assert False, "force_flush raised an exception" self.metric_reader.collect() metrics_by_name: Dict[str, List[Any]] = {} - data = self.metric_reader.get_metrics_data() - for resource_metric in (data and data.resource_metrics) or []: + metrics_data = self.metric_reader.get_metrics_data() + resource_metrics = ( + metrics_data and metrics_data.resource_metrics + ) or [] + for resource_metric in resource_metrics: for scope_metric in resource_metric.scope_metrics or []: for metric in scope_metric.metrics or []: points = metric.data.data_points or [] metrics_by_name.setdefault(metric.name, []).extend(points) - return metrics_by_name + return metrics_by_name, resource_metrics + + def _assert_metric_scope_schema_urls( + self, resource_metrics: List[Any], expected_schema_url: str + ) -> None: + for resource_metric in resource_metrics: + for scope_metric in resource_metric.scope_metrics: + self.assertEqual( + scope_metric.scope.schema_url, expected_schema_url + ) diff --git a/util/opentelemetry-util-genai/tests/test_utils.py b/util/opentelemetry-util-genai/tests/test_utils.py index 851670026d3..d229d4b4b62 100644 --- a/util/opentelemetry-util-genai/tests/test_utils.py +++ b/util/opentelemetry-util-genai/tests/test_utils.py @@ -25,7 +25,9 @@ ) from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk._logs.export import ( - InMemoryLogRecordExporter, + InMemoryLogExporter as InMemoryLogRecordExporter, +) +from opentelemetry.sdk._logs.export import ( SimpleLogRecordProcessor, ) from opentelemetry.sdk.trace import ReadableSpan, TracerProvider @@ -457,6 +459,27 @@ def test_llm_span_uses_expected_schema_url(self): == Schemas.V1_37_0.value ) + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="EVENT_ONLY", + emit_event="true", + ) + def test_llm_log_uses_expected_schema_url(self): + invocation = LLMInvocation( + request_model="schema-model", + provider="schema-provider", + ) + + self.telemetry_handler.start_llm(invocation) + invocation.output_messages = [_create_output_message()] + self.telemetry_handler.stop_llm(invocation) + + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 1) + self.assertEqual( + logs[0].instrumentation_scope.schema_url, Schemas.V1_37_0.value + ) + @patch_env_vars( stability_mode="gen_ai_latest_experimental", content_capturing="SPAN_ONLY", From d01b7bf0b6c6e8be56f97b28c002c719a2b82ffe Mon Sep 17 00:00:00 2001 From: "Anuraag (Rag) Agrawal" Date: Thu, 12 Mar 2026 18:57:36 +0900 Subject: [PATCH 15/78] fix: don't import module in unwrap if not already imported (#4321) * fix: don't import module in unwrap if not already * Changelog * Make test clearer * Update CHANGELOG.md Co-authored-by: Riccardo Magliocchetti --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 ++ .../src/opentelemetry/instrumentation/utils.py | 4 ++++ opentelemetry-instrumentation/tests/test_utils.py | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 041d0a1233a..2a84f273f1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix intermittent `Core Contrib Test` CI failures caused by GitHub git CDN SHA propagation lag by installing core packages from the already-checked-out local copy instead of a second git clone ([#4305](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4305)) +- Don't import module in unwrap if not already imported + ([#4321](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4321)) ### Breaking changes diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py index 37e6c674f91..a672809fbd3 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py @@ -14,6 +14,7 @@ from __future__ import annotations +import sys import urllib.parse from contextlib import contextmanager from importlib import import_module @@ -103,6 +104,9 @@ def unwrap(obj: object, attr: str): 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) diff --git a/opentelemetry-instrumentation/tests/test_utils.py b/opentelemetry-instrumentation/tests/test_utils.py index 11a3598bdc0..04ccfc0cbc2 100644 --- a/opentelemetry-instrumentation/tests/test_utils.py +++ b/opentelemetry-instrumentation/tests/test_utils.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys import unittest from http import HTTPStatus @@ -295,13 +296,21 @@ def test_raises_import_error_if_path_not_well_formed(self): unwrap(WrappedClass, "method") self.assertFalse(isinstance(instance.method, BaseObjectProxy)) - def test_raises_import_error_if_cannot_find_module(self): + def test_noop_if_module_not_imported(self): + # A module that exists but hasn't been imported, treated + # as no-op. + self.assertNotIn("email.generator", sys.modules) + unwrap("email.generator.BytesGenerator", "flatten") + self.assertNotIn("email.generator", sys.modules) + + def test_noop_if_cannot_find_module(self): self._wrap_method() instance = WrappedClass() self.assertTrue(isinstance(instance.method, BaseObjectProxy)) - with self.assertRaisesRegex(ImportError, "No module named 'does'"): - unwrap("does.not.exist.WrappedClass", "method") + # Treated same as an existing module that hasn't been imported, + # as a no-op. + unwrap("does.not.exist.WrappedClass", "method") unwrap(WrappedClass, "method") self.assertFalse(isinstance(instance.method, BaseObjectProxy)) From b35be0d73eec2206d40dcfa78a04ac1888335fd3 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 12 Mar 2026 11:07:32 +0100 Subject: [PATCH 16/78] Silence some pylint4 warnings (#4272) * pylint: use unnecessary-dunder-call instead of E1101 Since pylint 4 now raises a different error code * opentelemetry-instrumentation-sqlite3: fix pylint warnings Possibly using variable 'root_span' before assignment (possibly-used-before-assignment) Possibly using variable 'child_span' before assignment (possibly-used-before-assignment) * opentelemetry-instrumentation-botocore: silence a bunch of pylint warnings In the form of Possibly using variable '' before assignment (possibly-used-before-assignment) * opentelemetry-instrumentation-redis: remove useless return spotted by pylint * opentelemetry-instrumentation-fastapi: silence some pylint warnings E0102: function already defined line 2034 (function-redefined) * opentelemetry-instrumentation-google-genai: fix pylint warnings Assisted by Cursor. * opentelemetry-instrumentation-openai-v2: fix pylint 4 errors Assisted by Cursor * opentelemetry-instrumentation-elasticsearch: fix pylint 4 errors Assisted by Cursor. * opentelemetry-instrumentation-pika: fix pylint 4 errors Assisted by cursor. * opentelemetry-instrumentation-starlette: fix pylint 4 errors * opentelemetry-instrumentation: fix pylint 4 errors Assisted by Cursor. * opentelemetry-util-http: fix pylint 4 errors --- .../tests/generate_content/base.py | 3 +- .../tests/test_async_chat_completions.py | 9 +++++ .../tests/test_chat_completions.py | 12 ++++++ .../tests/test_botocore_bedrock.py | 37 +++++++++++++++++++ .../instrumentation/celery/__init__.py | 6 +-- .../django/middleware/otel_middleware.py | 2 +- .../tests/test_elasticsearch.py | 1 + .../instrumentation/falcon/__init__.py | 2 +- .../tests/test_fastapi_instrumentation.py | 28 +++++++------- .../instrumentation/flask/__init__.py | 4 +- .../instrumentation/pika/pika_instrumentor.py | 1 + .../instrumentation/pyramid/callbacks.py | 4 +- .../instrumentation/redis/__init__.py | 1 - .../instrumentation/remoulade/__init__.py | 4 +- .../tests/test_sqlite3.py | 2 + .../tests/test_starlette_instrumentation.py | 4 +- .../instrumentation/tornado/__init__.py | 4 +- .../opentelemetry/instrumentation/_semconv.py | 2 +- .../instrumentation/bootstrap.py | 3 +- .../src/opentelemetry/util/http/httplib.py | 6 ++- 20 files changed, 98 insertions(+), 37 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/base.py b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/base.py index ebaeeb8748d..070939bb14b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/base.py +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/base.py @@ -124,8 +124,7 @@ def _create_stream_mock(self, e=None): mock = unittest.mock.MagicMock() def _default_impl(*args, **kwargs): - for response in self._responses: - yield response + yield from self._responses if not e: mock.side_effect = _default_impl diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py index 5da88e6b5a1..c19a8b3d5ba 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_chat_completions.py @@ -418,6 +418,9 @@ async def test_chat_completion_with_raw_response_streaming( response = raw_response.parse() message_content = "" + response_stream_usage = None + response_stream_model = None + response_stream_id = None async for chunk in response: if chunk.choices: message_content += chunk.choices[0].delta.content or "" @@ -983,6 +986,9 @@ async def test_async_chat_completion_multiple_choices_streaming( stream_options={"include_usage": True}, ) + response_stream_usage = None + response_stream_model = None + response_stream_id = None # two strings for each choice response_stream_result = ["", ""] finish_reasons = ["", ""] @@ -1203,6 +1209,9 @@ async def async_chat_completion_multiple_tools_streaming( ) finish_reason = None + response_stream_usage = None + response_stream_model = None + response_stream_id = None # two tools tool_names = ["", ""] tool_call_ids = ["", ""] diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py index 4862460ddf2..3e4df914dc0 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_completions.py @@ -561,6 +561,9 @@ def test_chat_completion_with_raw_response_streaming( response = raw_response.parse() message_content = "" + response_stream_usage = None + response_stream_model = None + response_stream_id = None for chunk in response: if chunk.choices: message_content += chunk.choices[0].delta.content or "" @@ -1083,6 +1086,9 @@ def test_chat_completion_multiple_choices_streaming( # two strings for each choice response_stream_result = ["", ""] finish_reasons = ["", ""] + response_stream_usage = None + response_stream_model = None + response_stream_id = None for chunk in response_0: if chunk.choices: for choice in chunk.choices: @@ -1274,6 +1280,9 @@ def test_chat_completion_with_context_manager_streaming( stream_options={"include_usage": True}, ) as response: message_content = "" + response_stream_usage = None + response_stream_model = None + response_stream_id = None for chunk in response: if chunk.choices: message_content += chunk.choices[0].delta.content or "" @@ -1345,6 +1354,9 @@ def chat_completion_multiple_tools_streaming( ) finish_reason = None + response_stream_usage = None + response_stream_model = None + response_stream_id = None # two tools tool_names = ["", ""] tool_call_ids = ["", ""] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py index a8a0afe1120..ef0146314f1 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py @@ -1485,7 +1485,12 @@ def test_invoke_model_with_content( "content": "\n\nA man stands before a crowd of people", } finish_reason = "length" + else: + pytest.xfail("model family not handled: {model_family}") + return + assert_message_in_logs(logs[0], "gen_ai.user.message", user_content, span) + choice_body = { "index": 0, "finish_reason": finish_reason, @@ -1621,6 +1626,9 @@ def test_invoke_model_with_content_different_events( system = anthropic_claude_system() finish_reason = "end_turn" choice_content = [{"type": "text", "text": "This is a test"}] + else: + pytest.xfail("llm_model_value not handled: {llm_model_value}") + return body = get_invoke_model_body( llm_model_value, @@ -2060,6 +2068,9 @@ def test_invoke_model_with_content_tool_call( elif model_family == "anthropic.claude": llm_model_value = "us.anthropic.claude-3-5-sonnet-20240620-v1:0" llm_model_config = AnthropicClaudeModel + else: + pytest.xfail("model family not handled: {model_family}") + return invoke_model_tool_call( span_exporter, @@ -2143,6 +2154,10 @@ def test_invoke_model_no_content( elif model_family == "mistral.mistral": choice_message = {} finish_reason = "length" + else: + pytest.xfail("model family not handled: {model_family}") + return + choice_body = { "index": 0, "finish_reason": finish_reason, @@ -2173,6 +2188,9 @@ def test_invoke_model_no_content_different_events( messages = anthropic_claude_messages() system = anthropic_claude_system() finish_reason = "end_turn" + else: + pytest.xfail("llm_model_value not handled: {llm_model_value}") + return body = get_invoke_model_body( llm_model_value, @@ -2226,6 +2244,9 @@ def test_invoke_model_no_content_tool_call( elif model_family == "anthropic.claude": llm_model_value = "us.anthropic.claude-3-5-sonnet-20240620-v1:0" llm_model_config = AnthropicClaudeModel + else: + pytest.xfail("model family not handled: {model_family}") + return invoke_model_tool_call( span_exporter, @@ -2378,6 +2399,10 @@ def test_invoke_model_with_response_stream_with_content( {"text": "\nHello! I am a computer program designed to"} ] } + else: + pytest.xfail("model family not handled: {model_family}") + return + choice_body = { "index": 0, "finish_reason": finish_reason, @@ -2410,6 +2435,9 @@ def test_invoke_model_with_response_stream_with_content_different_events( system = anthropic_claude_system() finish_reason = "end_turn" choice_content = [{"text": "This is a test", "type": "text"}] + else: + pytest.xfail("llm_model_value not handled: {llm_model_value}") + return max_tokens = 10 body = get_invoke_model_body( @@ -2642,6 +2670,9 @@ def test_invoke_model_with_response_stream_with_content_tool_call( elif model_family == "anthropic.claude": llm_model_value = "us.anthropic.claude-3-5-sonnet-20240620-v1:0" llm_model_config = AnthropicClaudeModel + else: + pytest.xfail("model family not handled: {model_family}") + return invoke_model_with_response_stream_tool_call( span_exporter, @@ -2768,6 +2799,9 @@ def test_invoke_model_with_response_stream_no_content_different_events( messages = anthropic_claude_messages() system = anthropic_claude_system() finish_reason = "end_turn" + else: + pytest.xfail("llm_model_value not handled: {llm_model_value}") + return max_tokens = 10 body = get_invoke_model_body( @@ -2828,6 +2862,9 @@ def test_invoke_model_with_response_stream_no_content_tool_call( elif model_family == "anthropic.claude": llm_model_value = "us.anthropic.claude-3-5-sonnet-20240620-v1:0" llm_model_config = AnthropicClaudeModel + else: + pytest.xfail("model family not handled: {model_family}") + return invoke_model_with_response_stream_tool_call( span_exporter, diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py index 8bd10a0a58a..3d6691f3824 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py @@ -182,7 +182,7 @@ def _trace_prerun(self, *args, **kwargs): ) activation = trace.use_span(span, end_on_exit=True) - activation.__enter__() # pylint: disable=E1101 + activation.__enter__() # pylint: disable=unnecessary-dunder-call utils.attach_context(task, task_id, span, activation, token) def _trace_postrun(self, *args, **kwargs): @@ -247,7 +247,7 @@ def _trace_before_publish(self, *args, **kwargs): utils.set_attributes_from_context(span, kwargs) activation = trace.use_span(span, end_on_exit=True) - activation.__enter__() # pylint: disable=E1101 + activation.__enter__() # pylint: disable=unnecessary-dunder-call utils.attach_context( task, task_id, span, activation, None, is_publish=True @@ -274,7 +274,7 @@ def _trace_after_publish(*args, **kwargs): _, activation, _ = ctx - activation.__exit__(None, None, None) # pylint: disable=E1101 + activation.__exit__(None, None, None) # pylint: disable=unnecessary-dunder-call utils.detach_context(task, task_id, is_publish=True) @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 5f142b614d1..7194d7958f5 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -271,7 +271,7 @@ def process_request(self, request): span.set_attribute(key, value) activation = use_span(span, end_on_exit=True) - activation.__enter__() # pylint: disable=E1101 + activation.__enter__() # pylint: disable=unnecessary-dunder-call request_start_time = default_timer() request.META[self._environ_timer_key] = request_start_time request.META[self._environ_activation_key] = activation diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py index d8386a2f4e6..1ec5ded7491 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py @@ -42,6 +42,7 @@ major_version, minor_version = elasticsearch.VERSION[:2] +helpers = None if major_version == 8: from . import helpers_es8 as helpers # pylint: disable=no-name-in-module elif major_version == 7: diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 09429f8bb52..2da0f9964f5 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -346,7 +346,7 @@ def _handle_exception(self, *args): return super()._handle_exception(*args) def __call__(self, env, start_response): - # pylint: disable=E1101 + # pylint: disable=unnecessary-dunder-call # pylint: disable=too-many-locals # pylint: disable=too-many-branches if self._otel_excluded_urls.url_disabled(env.get("PATH_INFO", "/")): diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index a2a8fb47750..aa6189a60ec 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -238,27 +238,27 @@ def _create_fastapi_app(): custom_router = fastapi.APIRouter(route_class=CustomRoute) @sub_app.get("/home") - async def _(): + async def _home(): return {"message": "sub hi"} @app.get("/foobar") - async def _(): + async def _foobar(): return {"message": "hello world"} @app.get("/user/{username}") - async def _(username: str): + async def _user(username: str): return {"message": username} @app.get("/exclude/{param}") - async def _(param: str): + async def _exclude(param: str): return {"message": param} @app.get("/healthzz") - async def _(): + async def _health(): return {"message": "ok"} @app.get("/error") - async def _(): + async def _error(): raise UnhandledException("This is an unhandled exception") @custom_router.get("/success") @@ -1022,27 +1022,27 @@ def _create_fastapi_app(): custom_router = fastapi.APIRouter(route_class=CustomRoute) @sub_app.get("/home") - async def _(): + async def _home(): return {"message": "sub hi"} @app.get("/foobar") - async def _(): + async def _foobar(): return {"message": "hello world"} @app.get("/user/{username}") - async def _(username: str): + async def _user(username: str): return {"message": username} @app.get("/exclude/{param}") - async def _(param: str): + async def _exclude(param: str): return {"message": param} @app.get("/healthzz") - async def _(): + async def _health(): return {"message": "ok"} @app.get("/error") - async def _(): + async def _error(): raise UnhandledException("This is an unhandled exception") @custom_router.get("/success") @@ -1965,7 +1965,7 @@ async def _(*_): return PlainTextResponse("", status_code) @self.app.get("/foobar") - async def _(): + async def _foobar(): self.request_trace_id = ( trace.get_current_span().get_span_context().trace_id ) @@ -2032,7 +2032,7 @@ def test_middleware_exceptions(self): """Exceptions from user middlewares are recorded in the active span""" @self.app.get("/foobar") - async def _(): + async def _foobar(): return PlainTextResponse("Hello World") @self.app.middleware("http") diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py index c66e8fa10d1..f69470ab9ed 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -518,7 +518,7 @@ def _before_request(): span.set_attributes(custom_attributes) activation = trace.use_span(span, end_on_exit=True) - activation.__enter__() # pylint: disable=E1101 + activation.__enter__() # pylint: disable=unnecessary-dunder-call flask_request_environ[_ENVIRON_ACTIVATION_KEY] = activation flask_request_environ[_ENVIRON_REQCTX_REF_KEY] = _request_ctx_ref() flask_request_environ[_ENVIRON_SPAN_KEY] = span @@ -555,7 +555,7 @@ def _wrapped_teardown_request( excluded_urls=None, ): def _teardown_request(exc): - # pylint: disable=E1101 + # pylint: disable=unnecessary-dunder-call if excluded_urls and excluded_urls.url_disabled(flask.request.url): return diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/pika_instrumentor.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/pika_instrumentor.py index 7b84f892299..8935d239507 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/pika_instrumentor.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/pika_instrumentor.py @@ -60,6 +60,7 @@ def _instrument_channel_consumers( tracer: Tracer, consume_hook: utils.HookT = utils.dummy_callback, ) -> Any: + consumer_infos = None if isinstance(channel, BlockingChannel): consumer_infos = channel._consumer_infos elif isinstance(channel, Channel): diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index 68d51bf1559..c665fdc3f89 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -148,7 +148,7 @@ def _before_traversal(event): span.set_attributes(custom_attributes) activation = trace.use_span(span, end_on_exit=True) - activation.__enter__() # pylint: disable=E1101 + activation.__enter__() # pylint: disable=unnecessary-dunder-call request_environ[_ENVIRON_ACTIVATION_KEY] = activation request_environ[_ENVIRON_SPAN_KEY] = span if token: @@ -212,7 +212,7 @@ def disabled_tween(request): # make a request tracing function # pylint: disable=too-many-branches def trace_tween(request): - # pylint: disable=E1101, too-many-locals + # pylint: disable=unnecessary-dunder-call, too-many-locals if _excluded_urls.url_disabled(request.url): request.environ[_ENVIRON_ENABLED_KEY] = False # short-circuit when we don't want to trace anything diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py index 8a4f93329d0..77c3ac31c3a 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py @@ -698,7 +698,6 @@ def uninstrument_client( _logger.warning( "Attempting to un-instrument Redis connection that wasn't instrumented" ) - return def instrumentation_dependencies(self) -> Collection[str]: """Return a list of python packages with versions that the will be instrumented.""" diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/__init__.py b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/__init__.py index 28a41b6a6cf..8a75448f485 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/__init__.py @@ -90,7 +90,7 @@ def before_process_message(self, _broker, message): ) activation = trace.use_span(span, end_on_exit=True) - activation.__enter__() # pylint: disable=E1101 + activation.__enter__() # pylint: disable=unnecessary-dunder-call utils.attach_span( self._span_registry, message.message_id, (span, activation) @@ -142,7 +142,7 @@ def before_enqueue(self, _broker, message, delay): ) activation = trace.use_span(span, end_on_exit=True) - activation.__enter__() # pylint: disable=E1101 + activation.__enter__() # pylint: disable=unnecessary-dunder-call utils.attach_span( self._span_registry, diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py b/instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py index 3d8ba2c4aaa..7c19f2a9ab6 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py @@ -54,6 +54,8 @@ def validate_spans(self, span_name): spans = self.memory_exporter.get_finished_spans() self.memory_exporter.clear() self.assertEqual(len(spans), 2) + root_span = None + child_span = None for span in spans: if span.name == "rootSpan": root_span = span diff --git a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py index a2a22a8e65c..0420df7bc50 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py @@ -624,7 +624,7 @@ def create_starlette_app(): app = applications.Starlette() @app.route("/foobar") - def _(request): + def _foobar(request): return PlainTextResponse( content="hi", headers={ @@ -637,7 +637,7 @@ def _(request): ) @app.websocket_route("/foobar_web") - async def _(websocket: WebSocket) -> None: + async def _foobar_web(websocket: WebSocket) -> None: message = await websocket.receive() if message.get("type") == "websocket.connect": await websocket.send( diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py index 190ee02cc83..934d9667d1a 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py @@ -776,7 +776,7 @@ def _start_span(tracer, handler, sem_conv_opt_in_mode) -> _TraceContext: span.set_attributes(custom_attributes) activation = trace.use_span(span, end_on_exit=True) - activation.__enter__() # pylint: disable=E1101 + activation.__enter__() # pylint: disable=unnecessary-dunder-call ctx = _TraceContext(activation, span, token) setattr(handler, _HANDLER_CONTEXT_KEY, ctx) @@ -829,7 +829,7 @@ def _finish_span(tracer, handler, error, sem_conv_opt_in_mode): if len(custom_attributes) > 0: ctx.span.set_attributes(custom_attributes) - ctx.activation.__exit__(*finish_args) # pylint: disable=E1101 + ctx.activation.__exit__(*finish_args) # pylint: disable=unnecessary-dunder-call if ctx.token: context.detach(ctx.token) delattr(handler, _HANDLER_CONTEXT_KEY) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index e30cdf2dfbc..ccf1f392025 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -327,7 +327,7 @@ def set_int_attribute( try: result[key] = int(value) except ValueError: - return + pass def _set_http_method( diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py index cc0ac68f1cf..3fbee088e43 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py @@ -117,8 +117,7 @@ def _is_installed(req): def _find_installed_libraries(default_instrumentations, libraries): - for lib in default_instrumentations: - yield lib + yield from default_instrumentations for lib in libraries: if _is_installed(lib["library"]): diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py index c969710cd3f..2a3723c9275 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py @@ -95,6 +95,7 @@ def trysetip( return True sock = "" + ip = None try: sock: typing.Optional[socket.socket] = conn.sock logger.debug("Got socket: %s", sock) @@ -112,8 +113,9 @@ def trysetip( stack_info=True, ) else: - for span in spanlist: - span.set_attribute(NET_PEER_IP, ip) + if ip is not None: + for span in spanlist: + span.set_attribute(NET_PEER_IP, ip) return True From 97bd32d3a052dc63786063276927728c827fc106 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 10:14:07 +0000 Subject: [PATCH 17/78] build(deps): bump django in /tests/opentelemetry-docker-tests/tests (#4299) Bumps [django](https://github.com/django/django) from 4.2.17 to 4.2.29. - [Commits](https://github.com/django/django/compare/4.2.17...4.2.29) --- updated-dependencies: - dependency-name: django dependency-version: 4.2.29 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- tests/opentelemetry-docker-tests/tests/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/opentelemetry-docker-tests/tests/test-requirements.txt b/tests/opentelemetry-docker-tests/tests/test-requirements.txt index 8bac6ab055e..434f44d5975 100644 --- a/tests/opentelemetry-docker-tests/tests/test-requirements.txt +++ b/tests/opentelemetry-docker-tests/tests/test-requirements.txt @@ -16,7 +16,7 @@ click-plugins==1.1.1 click-repl==0.3.0 cryptography==45.0.7 distro==1.9.0 -Django==4.2.17 +Django==4.2.29 dnspython==2.6.1 docker==5.0.3 docker-compose==1.29.2 From 78c948b15f0749e3cb23a98e58d4b1cad9ddf36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Deveaux?= Date: Thu, 12 Mar 2026 11:35:42 +0100 Subject: [PATCH 18/78] feat: add support for capture_parameters to Psycopg2Instrumentor (#4212) * feat: add support for capture_parameters to Psycopg2Instrumentor * Update CHANGELOG.md --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 + .../instrumentation/psycopg2/__init__.py | 15 ++++++ .../tests/test_psycopg2_instrumentation.py | 47 ++++++++++++++++++- .../tests/test_psycopg2_integration.py | 21 +++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a84f273f1b..76560ebefcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4289](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4289)) - `opentelemetry-instrumentation`: Add support for wrapt 2.x ([#4203](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4203)) +- `opentelemetry-instrumentation-psycopg2`: Add parameter `capture_parameters` to instrumentor. + ([#4212](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4212)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py index d1753af6a93..4c8b1b6e024 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py @@ -136,6 +136,19 @@ Warning: Capture of sqlcomment in ``db.statement`` may have high cardinality without platform normalization. See `Semantic Conventions for database spans `_ for more information. +Capture parameters +****************** +By default, only statements are captured, without the associated query parameters. +To capture query parameters in the span attribute `db.statement.parameters`, enable `capture_parameters`. + +.. code:: python + + from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor + + Psycopg2Instrumentor().instrument( + capture_parameters=True, + ) + API --- """ @@ -213,6 +226,7 @@ def _instrument(self, **kwargs): enable_attribute_commenter = kwargs.get( "enable_attribute_commenter", False ) + capture_parameters = kwargs.get("capture_parameters", False) dbapi.wrap_connect( __name__, psycopg2, @@ -225,6 +239,7 @@ def _instrument(self, **kwargs): enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, enable_attribute_commenter=enable_attribute_commenter, + capture_parameters=capture_parameters, ) def _uninstrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_instrumentation.py b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_instrumentation.py index 93a17d9ed1d..27b8618852a 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_instrumentation.py @@ -15,14 +15,21 @@ from unittest import TestCase from unittest.mock import Mock, call, patch +import psycopg2 + from opentelemetry.instrumentation.auto_instrumentation._load import ( _load_instrumentors, ) -from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor +from opentelemetry.instrumentation.psycopg2 import ( + DatabaseApiIntegration, + Psycopg2Instrumentor, +) from opentelemetry.instrumentation.psycopg2.package import ( _instruments_psycopg2, _instruments_psycopg2_binary, ) +from opentelemetry.instrumentation.psycopg2.version import __version__ +from opentelemetry.test.test_base import TestBase class TestPsycopg2InstrumentationDependencies(TestCase): @@ -160,3 +167,41 @@ def _instrumentation_loaded_successfully_call(): mock_logger.debug.assert_has_calls( [_instrumentation_loaded_successfully_call()] ) + + +@patch("opentelemetry.instrumentation.psycopg2.dbapi") +class TestPsycopg2InstrumentorParameters(TestBase): + def tearDown(self): + super().tearDown() + with self.disable_logging(): + Psycopg2Instrumentor().uninstrument() + + def test_instrument_defaults(self, mock_dbapi): # pylint: disable=no-self-use + Psycopg2Instrumentor().instrument() + + mock_dbapi.wrap_connect.assert_called_once_with( + "opentelemetry.instrumentation.psycopg2", + psycopg2, + "connect", + "postgresql", + { + "database": "info.dbname", + "port": "info.port", + "host": "info.host", + "user": "info.user", + }, + version=__version__, + tracer_provider=None, + db_api_integration_factory=DatabaseApiIntegration, + enable_commenter=False, + commenter_options={}, + enable_attribute_commenter=False, + capture_parameters=False, + ) + + def test_instrument_capture_parameters(self, mock_dbapi): + Psycopg2Instrumentor().instrument(capture_parameters=True) + + self.assertTrue( + mock_dbapi.wrap_connect.call_args.kwargs["capture_parameters"] + ) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py index a1477278db7..2b985dc1806 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py @@ -371,3 +371,24 @@ def test_no_op_tracer_provider(self): cursor.execute(query) spans_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans_list), 0) + + def test_span_capture_params_deactivated_by_default(self): + Psycopg2Instrumentor().instrument() + cnx = psycopg2.connect(database="test") + cursor = cnx.cursor() + query = "SELECT * FROM test WHERE id = %s AND name = %s" + cursor.execute(query, (42, "John Doe")) + spans_list = self.memory_exporter.get_finished_spans() + self.assertNotIn("db.statement.parameters", spans_list[0].attributes) + + def test_span_capture_params_activated(self): + Psycopg2Instrumentor().instrument(capture_parameters=True) + cnx = psycopg2.connect(database="test") + cursor = cnx.cursor() + query = "SELECT * FROM test WHERE id = %s AND name = %s" + cursor.execute(query, (42, "John Doe")) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual( + spans_list[0].attributes["db.statement.parameters"], + "(42, 'John Doe')", + ) From 22879d6b9fd252dcf5a77ec229e497105717d9b4 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Thu, 12 Mar 2026 14:59:20 +0100 Subject: [PATCH 19/78] Build list of required jobs in generate-workflow (#4326) * Build list of required jobs in generate-workflow Dump the list of all the jobs in the same format that is required for configuration in opentelemetry-admin terraform config files so that we don't miss required jobs. * Serialize also misc jobs * Document what this script is about --- .github/workflows/generate_required_checks.py | 42 +++++++++++++++++++ .gitignore | 3 ++ tox.ini | 1 + 3 files changed, 46 insertions(+) create mode 100644 .github/workflows/generate_required_checks.py diff --git a/.github/workflows/generate_required_checks.py b/.github/workflows/generate_required_checks.py new file mode 100644 index 00000000000..8e9185f76ec --- /dev/null +++ b/.github/workflows/generate_required_checks.py @@ -0,0 +1,42 @@ +""" +This script builds a text file with the list of required checks based on +the tox environments. Similarly to the system we are using to build the +github workflows. +The output is in the format than can be cut-and-pasted into the python-contrib +terraform configuration in the admin repository. +""" + +from pathlib import Path + +from generate_workflows_lib import ( + get_lint_job_datas, + get_misc_job_datas, + get_test_job_datas, + get_tox_envs, +) + +tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini") + + +def get_gh_contexts_from_jobs(job_datas): + def get_job_name(job): + if isinstance(job, str): + return job + return job["ui_name"] + + return [ + f""" {{ context = "{get_job_name(job)}" }},\n""" + for job in job_datas + ] + + +jobs = sorted( + get_gh_contexts_from_jobs(get_lint_job_datas(get_tox_envs(tox_ini_path))) + + get_gh_contexts_from_jobs( + get_test_job_datas(get_tox_envs(tox_ini_path), ["ubuntu-latest"]) + ) + + get_gh_contexts_from_jobs(get_misc_job_datas(get_tox_envs(tox_ini_path))) +) +with open("opentelemetry-admin-jobs.txt", "w") as f: + for job in jobs: + f.write(job) diff --git a/.gitignore b/.gitignore index 1c32b4446a9..09141b12eb4 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,6 @@ target # Benchmark result files *-benchmark.json + +# opentelemetry-admin jobs +opentelemetry-admin-jobs.txt diff --git a/tox.ini b/tox.ini index 8c5ff3aca9e..fdfd33afd58 100644 --- a/tox.ini +++ b/tox.ini @@ -1117,6 +1117,7 @@ deps = commands = python {toxinidir}/.github/workflows/generate_workflows.py + python {toxinidir}/.github/workflows/generate_required_checks.py [testenv:shellcheck] From 2c758c7d66b553c3b189f4d5849d9c381acace1f Mon Sep 17 00:00:00 2001 From: Ridhima Satam Date: Thu, 12 Mar 2026 09:43:29 -0700 Subject: [PATCH 20/78] Add workflow type in genai utils (#4310) * Add workflow type in genai utils * fixed errors * fixed errors * fixed test * fixed test * fixed precommit * moved to unreleased * reordered --- util/opentelemetry-util-genai/CHANGELOG.md | 2 + .../src/opentelemetry/util/genai/types.py | 17 +++++ .../tests/test_workflow_invocation.py | 75 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 util/opentelemetry-util-genai/tests/test_workflow_invocation.py diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index 82f09188f90..1b0a444b95e 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Populate schema_url on metrics ([#4320](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4320)) +- Add workflow invocation type to genAI utils + ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4310](#4310)) ## Version 0.3b0 (2026-02-20) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py index 045a65b372e..fc5de2cdb0c 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py @@ -203,6 +203,23 @@ class GenAIInvocation: attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) +@dataclass +class WorkflowInvocation(GenAIInvocation): + """ + Represents predetermined static sequence of operations eg: Agent, LLM, tool, and retrieval invocations. + A workflow groups multiple operations together, accepting input(s) and producing final output(s). + """ + + name: str = "" + operation_name: str = "invoke_workflow" + input_messages: list[InputMessage] = field( + default_factory=_new_input_messages + ) + output_messages: list[OutputMessage] = field( + default_factory=_new_output_messages + ) + + @dataclass class LLMInvocation(GenAIInvocation): """ diff --git a/util/opentelemetry-util-genai/tests/test_workflow_invocation.py b/util/opentelemetry-util-genai/tests/test_workflow_invocation.py new file mode 100644 index 00000000000..c6f9bcdaecf --- /dev/null +++ b/util/opentelemetry-util-genai/tests/test_workflow_invocation.py @@ -0,0 +1,75 @@ +from opentelemetry.util.genai.types import ( + InputMessage, + OutputMessage, + Text, + WorkflowInvocation, +) + + +class TestWorkflowInvocation: # pylint: disable=no-self-use + def test_default_values(self): + invocation = WorkflowInvocation() + assert invocation.name == "" + assert invocation.operation_name == "invoke_workflow" + assert not invocation.input_messages + assert not invocation.output_messages + assert invocation.span is None + assert invocation.context_token is None + assert not invocation.attributes + + def test_custom_name(self): + invocation = WorkflowInvocation(name="customer_support_pipeline") + assert invocation.name == "customer_support_pipeline" + + def test_custom_operation_name(self): + invocation = WorkflowInvocation(operation_name="run_pipeline") + assert invocation.operation_name == "run_pipeline" + + def test_with_input_messages(self): + msg = InputMessage(role="user", parts=[Text(content="hello")]) + invocation = WorkflowInvocation(input_messages=[msg]) + assert len(invocation.input_messages) == 1 + assert invocation.input_messages[0].role == "user" + + def test_with_output_messages(self): + msg = OutputMessage( + role="assistant", parts=[Text(content="hi")], finish_reason="stop" + ) + invocation = WorkflowInvocation(output_messages=[msg]) + assert len(invocation.output_messages) == 1 + assert invocation.output_messages[0].finish_reason == "stop" + + def test_inherits_genai_invocation(self): + invocation = WorkflowInvocation(attributes={"key": "value"}) + assert invocation.attributes == {"key": "value"} + + def test_default_lists_are_independent(self): + """Ensure default factory creates separate list instances.""" + inv1 = WorkflowInvocation() + inv2 = WorkflowInvocation() + inv1.input_messages.append(InputMessage(role="user", parts=[])) + assert len(inv2.input_messages) == 0 + + def test_default_attributes_are_independent(self): + inv1 = WorkflowInvocation() + inv2 = WorkflowInvocation() + inv1.attributes["foo"] = "bar" + assert "foo" not in inv2.attributes + + def test_full_construction(self): + inp = InputMessage(role="user", parts=[Text(content="query")]) + out = OutputMessage( + role="assistant", + parts=[Text(content="answer")], + finish_reason="stop", + ) + invocation = WorkflowInvocation( + name="my_workflow", + operation_name="invoke_workflow", + input_messages=[inp], + output_messages=[out], + ) + assert invocation.name == "my_workflow" + assert len(invocation.input_messages) == 1 + assert len(invocation.output_messages) == 1 + assert invocation.output_messages[0].parts[0].content == "answer" From e1fbc0d62146ee41884a82fde97e387671337a34 Mon Sep 17 00:00:00 2001 From: deepanshuclickpost <152253074+deepanshuclickpost@users.noreply.github.com> Date: Fri, 13 Mar 2026 14:02:21 +0530 Subject: [PATCH 21/78] fix: Add recursion guard in LoggingHandler.emit to prevent deadlock (#4302) * fix: Add recursion guard in LoggingHandler.emit to prevent deadlock LoggingHandler.emit() can deadlock when _translate() triggers internal logging (e.g., _clean_extended_attribute calling _logger.warning() for invalid attribute types). The warning re-enters the handler chain on the same thread, creating infinite recursion that prevents the handler lock from ever being released, blocking all other threads. This adds a ContextVar-based guard that detects re-entrant calls to emit() on the same thread and skips the recursive call, preventing the deadlock while preserving all application logs. Fixes open-telemetry/opentelemetry-python#3858 Relates to open-telemetry/opentelemetry-python#3560 Relates to open-telemetry/opentelemetry-python#4585 * Update CHANGELOG.md --------- Co-authored-by: Deepanshu Kartikey Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 + .../instrumentation/logging/handler.py | 32 ++++++- .../tests/test_logging_handler_recursion.py | 91 +++++++++++++++++++ 3 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-logging/tests/test_logging_handler_recursion.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 76560ebefcb..2c4d7ebddd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4305](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4305)) - Don't import module in unwrap if not already imported ([#4321](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4321)) +- `opentelemetry-instrumentation-logging`: Add recursion guard in LoggingHandler.emit to prevent deadlock + ([#4302](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4302)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py index c9a890db8b4..aa8a319fd2a 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py @@ -18,6 +18,7 @@ import logging.config import threading import traceback +from contextvars import ContextVar from time import time_ns from typing import Callable @@ -35,6 +36,10 @@ from opentelemetry.semconv.attributes import exception_attributes from opentelemetry.util.types import _ExtendedAttributes +_internal_logger = logging.getLogger(__name__ + ".internal") +_internal_logger.propagate = False +_internal_logger.addHandler(logging.StreamHandler()) + def _setup_logging_handler( logger_provider: LoggerProvider, log_code_attributes: bool = False @@ -112,6 +117,8 @@ class LoggingHandler(logging.Handler): https://docs.python.org/3/library/logging.html """ + _is_emitting: ContextVar[bool] = ContextVar("_is_emitting", default=False) + def __init__( self, level: int = logging.NOTSET, @@ -203,9 +210,28 @@ def emit(self, record: logging.LogRecord) -> None: 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)) + # Prevent recursive logging that can cause infinite recursion or deadlock. + # During _translate(), internal OTel code (e.g., _clean_extended_attribute) + # may call _logger.warning() for invalid attributes. If the OTel + # LoggingHandler is in the logger chain, this warning re-enters emit(), + # creating an infinite loop that prevents the handler lock from ever + # being released, blocking all other threads. + # See: https://github.com/open-telemetry/opentelemetry-python/issues/3858 + + if self._is_emitting.get(): + _internal_logger.warning( + "LoggingHandler.emit detected recursive logging, skipping to prevent deadlock." + ) + return + token = self._is_emitting.set(True) + try: + logger = get_logger( + record.name, logger_provider=self._logger_provider + ) + if not isinstance(logger, NoOpLogger): + logger.emit(self._translate(record)) + finally: + self._is_emitting.reset(token) def flush(self) -> None: """ diff --git a/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging_handler_recursion.py b/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging_handler_recursion.py new file mode 100644 index 00000000000..3afc9986b10 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging_handler_recursion.py @@ -0,0 +1,91 @@ +# 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. + +import logging +import threading +import unittest + +from opentelemetry.instrumentation.logging.handler import LoggingHandler +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import ( + InMemoryLogExporter, + SimpleLogRecordProcessor, +) + + +class TestLoggingHandlerRecursionGuard(unittest.TestCase): + @staticmethod + def _create_handler(): + exporter = InMemoryLogExporter() + provider = LoggerProvider() + provider.add_log_record_processor(SimpleLogRecordProcessor(exporter)) + handler = LoggingHandler(logger_provider=provider) + return handler, exporter + + @staticmethod + def _make_record(msg="test"): + return logging.LogRecord( + name="test", + level=logging.INFO, + pathname="", + lineno=0, + msg=msg, + args=(), + exc_info=None, + ) + + def test_recursive_emit_is_skipped(self): + """Recursive emit() should be skipped to prevent deadlock. + Regression test for https://github.com/open-telemetry/opentelemetry-python/issues/3858 + """ + handler, exporter = self._create_handler() + token = handler._is_emitting.set(True) + handler.emit(self._make_record("should be skipped")) + self.assertEqual(len(exporter.get_finished_logs()), 0) + handler._is_emitting.reset(token) + + def test_normal_emit_works(self): + """Non-recursive emit() should process logs normally.""" + handler, exporter = self._create_handler() + handler.emit(self._make_record("should be captured")) + logs = exporter.get_finished_logs() + self.assertEqual(len(logs), 1) + self.assertEqual(logs[0].log_record.body, "should be captured") + + def test_is_emitting_resets_after_emit(self): + """Context must reset after emit(), allowing subsequent logs.""" + handler, exporter = self._create_handler() + handler.emit(self._make_record("first")) + self.assertFalse(handler._is_emitting.get()) + handler.emit(self._make_record("second")) + self.assertEqual(len(exporter.get_finished_logs()), 2) + + def test_is_emitting_is_isolated_across_threads(self): + """Emit context on one thread must not block other threads.""" + handler, exporter = self._create_handler() + token = handler._is_emitting.set(True) + + result = [False] + + def log_from_other_thread(): + handler.emit(self._make_record("from other thread")) + result[0] = True + + thread = threading.Thread(target=log_from_other_thread) + thread.start() + thread.join(timeout=5) + + self.assertTrue(result[0], "Other thread should not be blocked") + self.assertEqual(len(exporter.get_finished_logs()), 1) + handler._is_emitting.reset(token) From db201383ac8861cc328f7d6d18eaa2ed611e87f3 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 16 Mar 2026 05:44:22 -0400 Subject: [PATCH 22/78] push ci (#4333) --- .../src/generate_workflows_lib/lint.yml.j2 | 5 ++--- .../src/generate_workflows_lib/misc.yml.j2 | 5 ++--- .../src/generate_workflows_lib/test.yml.j2 | 5 ++--- .github/workflows/lint_0.yml | 5 ++--- .github/workflows/misc_0.yml | 5 ++--- .github/workflows/test_0.yml | 5 ++--- .github/workflows/test_1.yml | 5 ++--- .github/workflows/test_2.yml | 5 ++--- .github/workflows/test_3.yml | 5 ++--- 9 files changed, 18 insertions(+), 27 deletions(-) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 index 87fc1a0a0fe..ef5e417d423 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 @@ -5,9 +5,8 @@ name: Lint {{ file_number }} on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index 4bc5f38e87a..20ad381d4a0 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -5,9 +5,8 @@ name: Misc {{ file_number }} on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 index b8f45b840ff..a0041c8b630 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 @@ -5,9 +5,8 @@ name: Test {{ file_number }} on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint_0.yml index bfdbc0d81e2..fdd1a954a5a 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint_0.yml @@ -5,9 +5,8 @@ name: Lint 0 on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc_0.yml index 18a1a499a30..bf8b902de14 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc_0.yml @@ -5,9 +5,8 @@ name: Misc 0 on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index c867d4a3306..eeae3918222 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -5,9 +5,8 @@ name: Test 0 on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 80ba04b5454..585c331a906 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -5,9 +5,8 @@ name: Test 1 on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index 960662b33c9..b80cf7400e9 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -5,9 +5,8 @@ name: Test 2 on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: diff --git a/.github/workflows/test_3.yml b/.github/workflows/test_3.yml index 24625aa601a..4fbfa25749c 100644 --- a/.github/workflows/test_3.yml +++ b/.github/workflows/test_3.yml @@ -5,9 +5,8 @@ name: Test 3 on: push: - branches-ignore: - - 'release/*' - - 'otelbot/*' + branches: + - 'main' pull_request: permissions: From cf9979a1d5ebc1145b056afc5d1c93df72828f4f Mon Sep 17 00:00:00 2001 From: Surya Date: Tue, 17 Mar 2026 10:06:05 -0400 Subject: [PATCH 23/78] feat: wrappers for async responses methods. (#4325) * feat: wrappers for async responses methods. * wip: updating changelog. * wip: refactoring for precommit and linting. * refactor: adding defensive guard against stream's response. --- .../CHANGELOG.md | 2 + .../openai_v2/response_wrappers.py | 163 +++++++- .../tests/test_response_wrappers.py | 352 ++++++++++++++++++ 3 files changed, 515 insertions(+), 2 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 051ecac9a9c..c75cdf2f271 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3715](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3715)) - Add wrappers for OpenAI Responses API streams and response stream managers ([#4280](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4280)) +- Add async wrappers for OpenAI Responses API streams and response stream managers + ([#4325](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4325)) ## Version 2.3b0 (2025-12-24) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py index 360bde464c5..ce3375b8d5f 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging -from contextlib import ExitStack, contextmanager +from contextlib import AsyncExitStack, ExitStack, contextmanager from types import TracebackType from typing import TYPE_CHECKING, Callable, Generator, Generic, TypeVar @@ -53,6 +53,8 @@ ResponseStreamEvent, ) from openai.lib.streaming.responses._responses import ( + AsyncResponseStream, + AsyncResponseStreamManager, ResponseStream, ResponseStreamManager, ) # pylint: disable=no-name-in-module @@ -76,6 +78,16 @@ def _set_response_attributes( _set_invocation_response_attributes(invocation, result, capture_content) +def _get_stream_response(stream): + try: + return stream._response + except AttributeError: + try: + return stream.response + except AttributeError: + return None + + class _ResponseProxy(Generic[ResponseT]): def __init__(self, response: ResponseT, finalize: Callable[[], None]): self._response = response @@ -91,6 +103,21 @@ def __getattr__(self, name: str): return getattr(self._response, name) +class _AsyncResponseProxy(Generic[ResponseT]): + def __init__(self, response: ResponseT, finalize: Callable[[], None]): + self._response = response + self._finalize = finalize + + async def aclose(self) -> None: + try: + await self._response.aclose() + finally: + self._finalize() + + def __getattr__(self, name: str): + return getattr(self._response, name) + + class ResponseStreamWrapper(Generic[TextFormatT]): """Wrapper for OpenAI Responses API stream objects. @@ -172,7 +199,7 @@ def __getattr__(self, name: str): @property def response(self): - response = self.stream.response + response = _get_stream_response(self.stream) if response is None: return None return _ResponseProxy(response, lambda: self._stop(None)) @@ -303,3 +330,135 @@ def parse(self) -> "ResponseStreamManagerWrapper[TextFormatT]": # cleanup once wrapt 2 typing support is available (wrapt PR #3903). def __getattr__(self, name: str): return getattr(self._manager, name) + + +class AsyncResponseStreamWrapper(ResponseStreamWrapper[TextFormatT]): + """Wrapper for async OpenAI Responses API stream objects.""" + + stream: "AsyncResponseStream[TextFormatT]" + + async def __aenter__(self) -> "AsyncResponseStreamWrapper[TextFormatT]": + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + try: + if exc_type is not None: + self._fail( + str(exc_val), type(exc_val) if exc_val else Exception + ) + finally: + await self.close() + return False + + async def close(self) -> None: + try: + await self.stream.close() + finally: + self._stop(None) + + def __aiter__(self) -> "AsyncResponseStreamWrapper[TextFormatT]": + return self + + async def __anext__(self) -> "ResponseStreamEvent[TextFormatT]": + try: + event = await self.stream.__anext__() + except StopAsyncIteration: + self._stop(None) + raise + except Exception as error: + self._fail(str(error), type(error)) + raise + with self._safe_instrumentation("event processing"): + self.process_event(event) + return event + + async def get_final_response(self) -> "ParsedResponse[TextFormatT]": + await self.until_done() + return await self.stream.get_final_response() + + async def until_done(self) -> "AsyncResponseStreamWrapper[TextFormatT]": + async for _ in self: + pass + return self + + def parse(self) -> "AsyncResponseStreamWrapper[TextFormatT]": + raise NotImplementedError( + "AsyncResponseStreamWrapper.parse() is not implemented" + ) + + @property + def response(self): + response = _get_stream_response(self.stream) + if response is None: + return None + return _AsyncResponseProxy(response, lambda: self._stop(None)) + + +class AsyncResponseStreamManagerWrapper(Generic[TextFormatT]): + """Wrapper for async OpenAI Responses API stream managers.""" + + def __init__( + self, + manager: "AsyncResponseStreamManager[TextFormatT]", + handler: TelemetryHandler, + invocation: "LLMInvocation", + capture_content: bool, + ): + self._manager = manager + self._handler = handler + self._invocation = invocation + self._capture_content = capture_content + self._stream_wrapper: ( + AsyncResponseStreamWrapper[TextFormatT] | None + ) = None + + async def __aenter__(self) -> AsyncResponseStreamWrapper[TextFormatT]: + stream = await self._manager.__aenter__() + self._stream_wrapper = AsyncResponseStreamWrapper( + stream, + self._handler, + self._invocation, + self._capture_content, + ) + return self._stream_wrapper + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + suppressed = False + stream_wrapper = self._stream_wrapper + self._stream_wrapper = None + async with AsyncExitStack() as cleanup: + if stream_wrapper is not None: + + async def finalize_stream_wrapper() -> None: + if suppressed: + await stream_wrapper.__aexit__(None, None, None) + else: + await stream_wrapper.__aexit__( + exc_type, exc_val, exc_tb + ) + + cleanup.push_async_callback(finalize_stream_wrapper) + suppressed = await self._manager.__aexit__( + exc_type, exc_val, exc_tb + ) + return suppressed + + def parse(self) -> "AsyncResponseStreamManagerWrapper[TextFormatT]": + raise NotImplementedError( + "AsyncResponseStreamManagerWrapper.parse() is not implemented" + ) + + # TODO: Replace __getattr__ passthrough with wrapt.ObjectProxy in a future + # cleanup once wrapt 2 typing support is available (wrapt PR #3903). + def __getattr__(self, name: str): + return getattr(self._manager, name) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py index 803a55e4a8a..2789284b887 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py @@ -17,7 +17,10 @@ import pytest from opentelemetry.instrumentation.openai_v2.response_wrappers import ( + AsyncResponseStreamManagerWrapper, + AsyncResponseStreamWrapper, ResponseStreamManagerWrapper, + ResponseStreamWrapper, ) @@ -38,6 +41,32 @@ def __exit__(self, exc_type, exc_val, exc_tb): return self._suppressed +class _FakeAsyncManager: + def __init__(self, stream, suppressed=False, exit_error=None): + self._stream = stream + self._suppressed = suppressed + self._exit_error = exit_error + self.exit_args = None + + async def __aenter__(self): + return self._stream + + async def __aexit__(self, exc_type, exc_val, exc_tb): + self.exit_args = (exc_type, exc_val, exc_tb) + if self._exit_error is not None: + raise self._exit_error + return self._suppressed + + +def _noop_stop_llm(invocation): + del invocation + + +def _noop_fail_llm(invocation, error): + del invocation + del error + + def _make_wrapper(manager): handler = SimpleNamespace() invocation = SimpleNamespace(request_model=None) @@ -49,6 +78,47 @@ def _make_wrapper(manager): ) +def _make_stream_wrapper(stream, handler=None): + if handler is None: + handler = SimpleNamespace( + stop_llm=_noop_stop_llm, + fail_llm=_noop_fail_llm, + ) + invocation = SimpleNamespace(request_model=None) + return ResponseStreamWrapper( + stream=stream, + handler=handler, + invocation=invocation, + capture_content=False, + ) + + +def _make_async_manager_wrapper(manager): + handler = SimpleNamespace() + invocation = SimpleNamespace(request_model=None) + return AsyncResponseStreamManagerWrapper( + manager=manager, + handler=handler, + invocation=invocation, + capture_content=False, + ) + + +def _make_async_stream_wrapper(stream, handler=None): + if handler is None: + handler = SimpleNamespace( + stop_llm=_noop_stop_llm, + fail_llm=_noop_fail_llm, + ) + invocation = SimpleNamespace(request_model=None) + return AsyncResponseStreamWrapper( + stream=stream, + handler=handler, + invocation=invocation, + capture_content=False, + ) + + class _FakeStreamWrapper: def __init__(self): self.exit_args = None @@ -58,6 +128,62 @@ def __exit__(self, exc_type, exc_val, exc_tb): return False +class _FakeAsyncStreamWrapper: + def __init__(self): + self.exit_args = None + + async def __aexit__(self, exc_type, exc_val, exc_tb): + self.exit_args = (exc_type, exc_val, exc_tb) + return False + + +class _FakeAsyncResponse: + def __init__(self): + self.aclose_calls = 0 + + async def aclose(self): + self.aclose_calls += 1 + + +class _FakeSyncResponse: + def __init__(self): + self.close_calls = 0 + + def close(self): + self.close_calls += 1 + + +class _FakeAsyncStream: + def __init__( + self, + *, + events=None, + error=None, + final_response=None, + response=None, + ): + self._events = list(events or []) + self._error = error + self._final_response = final_response + self._response = response + self.close_calls = 0 + self.get_final_response_calls = 0 + + async def __anext__(self): + if self._events: + return self._events.pop(0) + if self._error is not None: + raise self._error + raise StopAsyncIteration + + async def close(self): + self.close_calls += 1 + + async def get_final_response(self): + self.get_final_response_calls += 1 + return self._final_response + + def test_manager_exit_forwards_exception_to_stream_wrapper(): manager = _FakeManager(stream=SimpleNamespace(), suppressed=False) wrapper = _make_wrapper(manager) @@ -104,3 +230,229 @@ def test_manager_exit_still_finalizes_stream_wrapper_when_manager_raises(): assert manager.exit_args == (ValueError, error, None) assert stream_wrapper.exit_args == (ValueError, error, None) assert wrapper._stream_wrapper is None + + +def test_stream_wrapper_response_falls_back_to_public_response_attr(): + response = _FakeSyncResponse() + stream = SimpleNamespace(response=response) + wrapper = _make_stream_wrapper(stream) + stopped = [] + + wrapper._stop = stopped.append + + wrapper.response.close() + + assert response.close_calls == 1 + assert stopped == [None] + + +@pytest.mark.asyncio +async def test_async_manager_exit_forwards_exception_to_stream_wrapper(): + manager = _FakeAsyncManager(stream=SimpleNamespace(), suppressed=False) + wrapper = _make_async_manager_wrapper(manager) + stream_wrapper = _FakeAsyncStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = ValueError("boom") + result = await wrapper.__aexit__(ValueError, error, None) + + assert result is False + assert manager.exit_args == (ValueError, error, None) + assert stream_wrapper.exit_args == (ValueError, error, None) + assert wrapper._stream_wrapper is None + + +@pytest.mark.asyncio +async def test_async_manager_enter_constructs_async_stream_wrapper(): + stream = _FakeAsyncStream() + manager = _FakeAsyncManager(stream=stream) + wrapper = _make_async_manager_wrapper(manager) + + async with wrapper as result: + assert isinstance(result, AsyncResponseStreamWrapper) + assert result.stream is stream + assert wrapper._stream_wrapper is result + + +@pytest.mark.asyncio +async def test_async_manager_exit_uses_none_exception_when_manager_suppresses(): + manager = _FakeAsyncManager(stream=SimpleNamespace(), suppressed=True) + wrapper = _make_async_manager_wrapper(manager) + stream_wrapper = _FakeAsyncStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = RuntimeError("ignored") + result = await wrapper.__aexit__(RuntimeError, error, None) + + assert result is True + assert manager.exit_args == (RuntimeError, error, None) + assert stream_wrapper.exit_args == (None, None, None) + assert wrapper._stream_wrapper is None + + +@pytest.mark.asyncio +async def test_async_manager_exit_still_finalizes_stream_wrapper_when_manager_raises(): + manager_error = RuntimeError("manager failure") + manager = _FakeAsyncManager( + stream=SimpleNamespace(), suppressed=False, exit_error=manager_error + ) + wrapper = _make_async_manager_wrapper(manager) + stream_wrapper = _FakeAsyncStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = ValueError("outer") + with pytest.raises(RuntimeError, match="manager failure"): + await wrapper.__aexit__(ValueError, error, None) + + assert manager.exit_args == (ValueError, error, None) + assert stream_wrapper.exit_args == (ValueError, error, None) + assert wrapper._stream_wrapper is None + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_exit_closes_without_exception(): + stream = _FakeAsyncStream() + wrapper = _make_async_stream_wrapper(stream) + stopped = [] + + wrapper._stop = stopped.append + + result = await wrapper.__aexit__(None, None, None) + + assert result is False + assert stream.close_calls == 1 + assert stopped == [None] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_exit_fails_and_closes_on_exception(): + stream = _FakeAsyncStream() + wrapper = _make_async_stream_wrapper(stream) + stopped = [] + failures = [] + + def record_failure(message, error_type): + failures.append((message, error_type)) + + wrapper._stop = stopped.append + wrapper._fail = record_failure + + error = ValueError("boom") + result = await wrapper.__aexit__(ValueError, error, None) + + assert result is False + assert stream.close_calls == 1 + assert stopped == [None] + assert failures == [("boom", ValueError)] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_close_closes_stream_and_stops(): + stream = _FakeAsyncStream() + wrapper = _make_async_stream_wrapper(stream) + stopped = [] + + wrapper._stop = stopped.append + + await wrapper.close() + + assert stream.close_calls == 1 + assert stopped == [None] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_processes_events_and_stops_on_completion(): + event = SimpleNamespace(type="response.created") + stream = _FakeAsyncStream(events=[event]) + wrapper = _make_async_stream_wrapper(stream) + processed = [] + stopped = [] + + wrapper.process_event = processed.append + wrapper._stop = stopped.append + + result = await wrapper.__anext__() + + assert result is event + assert processed == [event] + + with pytest.raises(StopAsyncIteration): + await wrapper.__anext__() + + assert stopped == [None] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_until_done_consumes_stream(): + events = [ + SimpleNamespace(type="response.created"), + SimpleNamespace(type="response.in_progress"), + ] + stream = _FakeAsyncStream(events=events) + wrapper = _make_async_stream_wrapper(stream) + processed = [] + stopped = [] + + wrapper.process_event = processed.append + wrapper._stop = stopped.append + + result = await wrapper.until_done() + + assert result is wrapper + assert processed == events + assert stopped == [None] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_fails_and_reraises_stream_errors(): + error = ValueError("boom") + stream = _FakeAsyncStream(error=error) + wrapper = _make_async_stream_wrapper(stream) + failures = [] + + def record_failure(message, error_type): + failures.append((message, error_type)) + + wrapper._fail = record_failure + + with pytest.raises(ValueError, match="boom"): + await wrapper.__anext__() + + assert failures == [("boom", ValueError)] + + +@pytest.mark.asyncio +async def test_async_stream_response_aclose_finalizes_wrapper(): + response = _FakeAsyncResponse() + stream = _FakeAsyncStream(response=response) + wrapper = _make_async_stream_wrapper(stream) + stopped = [] + + wrapper._stop = stopped.append + + await wrapper.response.aclose() + + assert response.aclose_calls == 1 + assert stopped == [None] + + +@pytest.mark.asyncio +async def test_async_stream_response_is_none_when_stream_has_no_response(): + wrapper = _make_async_stream_wrapper(SimpleNamespace()) + + assert wrapper.response is None + + +@pytest.mark.asyncio +async def test_async_stream_get_final_response_waits_for_completion(): + event = SimpleNamespace(type="response.in_progress") + final_response = SimpleNamespace(id="response_123") + stream = _FakeAsyncStream(events=[event], final_response=final_response) + wrapper = _make_async_stream_wrapper(stream) + + wrapper.process_event = lambda current: current + + result = await wrapper.get_final_response() + + assert result is final_response + assert stream.get_final_response_calls == 1 From 6a8a4fa6168c825d2f83232713520204537661b8 Mon Sep 17 00:00:00 2001 From: "Anuraag (Rag) Agrawal" Date: Tue, 17 Mar 2026 23:17:49 +0900 Subject: [PATCH 24/78] chore(util-genai): migrate handler metrics test to TestBase (#4332) * chore(util-genai): migrate handler metrics test to TestBase * Formatting --------- Co-authored-by: Riccardo Magliocchetti --- .../tests/test_handler_metrics.py | 72 ++++++------------- 1 file changed, 22 insertions(+), 50 deletions(-) diff --git a/util/opentelemetry-util-genai/tests/test_handler_metrics.py b/util/opentelemetry-util-genai/tests/test_handler_metrics.py index 6db12f0cd2c..b45383abfe7 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_metrics.py +++ b/util/opentelemetry-util-genai/tests/test_handler_metrics.py @@ -1,38 +1,22 @@ from __future__ import annotations -from typing import Any, Dict, List, Tuple -from unittest import TestCase +from typing import Any, Dict, List from unittest.mock import patch -from opentelemetry.sdk.metrics import MeterProvider -from opentelemetry.sdk.metrics.export import InMemoryMetricReader -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import SimpleSpanProcessor -from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( - InMemorySpanExporter, -) from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAI, ) from opentelemetry.semconv.schemas import Schemas +from opentelemetry.test.test_base import TestBase from opentelemetry.util.genai.handler import TelemetryHandler from opentelemetry.util.genai.types import Error, LLMInvocation _DEFAULT_SCHEMA_URL = Schemas.V1_37_0.value +SCOPE = "opentelemetry.util.genai.handler" -class TelemetryHandlerMetricsTest(TestCase): - def setUp(self) -> None: - self.metric_reader = InMemoryMetricReader() - self.meter_provider = MeterProvider( - metric_readers=[self.metric_reader] - ) - self.span_exporter = InMemorySpanExporter() - self.tracer_provider = TracerProvider() - self.tracer_provider.add_span_processor( - SimpleSpanProcessor(self.span_exporter) - ) +class TelemetryHandlerMetricsTest(TestBase): def test_stop_llm_records_duration_and_tokens(self) -> None: handler = TelemetryHandler( tracer_provider=self.tracer_provider, @@ -52,10 +36,8 @@ def test_stop_llm_records_duration_and_tokens(self) -> None: ): handler.stop_llm(invocation) - metrics, resource_metrics = self._harvest_metrics() - self._assert_metric_scope_schema_urls( - resource_metrics, _DEFAULT_SCHEMA_URL - ) + self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) + metrics = self._harvest_metrics() self.assertIn("gen_ai.client.operation.duration", metrics) duration_points = metrics["gen_ai.client.operation.duration"] self.assertEqual(len(duration_points), 1) @@ -110,10 +92,8 @@ def test_stop_llm_records_duration_and_tokens_with_additional_attributes( invocation.attributes = {"should not be on metrics": "value"} handler.stop_llm(invocation) - metrics, resource_metrics = self._harvest_metrics() - self._assert_metric_scope_schema_urls( - resource_metrics, _DEFAULT_SCHEMA_URL - ) + self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) + metrics = self._harvest_metrics() self.assertIn("gen_ai.client.operation.duration", metrics) duration_points = metrics["gen_ai.client.operation.duration"] self.assertIn("gen_ai.client.token.usage", metrics) @@ -148,10 +128,8 @@ def test_fail_llm_records_error_and_available_tokens(self) -> None: ): handler.fail_llm(invocation, error) - metrics, resource_metrics = self._harvest_metrics() - self._assert_metric_scope_schema_urls( - resource_metrics, _DEFAULT_SCHEMA_URL - ) + self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) + metrics = self._harvest_metrics() self.assertIn("gen_ai.client.operation.duration", metrics) duration_points = metrics["gen_ai.client.operation.duration"] self.assertEqual(len(duration_points), 1) @@ -177,35 +155,29 @@ def test_fail_llm_records_error_and_available_tokens(self) -> None: def _harvest_metrics( self, - ) -> Tuple[Dict[str, List[Any]], List[Any]]: + ) -> Dict[str, List[Any]]: """Returns (metrics_by_name, resource_metrics). metrics_by_name maps metric name to list of data points. resource_metrics is the raw ResourceMetrics list for scope-level assertions (e.g. schema_url). """ - try: - self.meter_provider.force_flush() - except Exception: # pylint: disable=broad-except - assert False, "force_flush raised an exception" - self.metric_reader.collect() + metrics = self.get_sorted_metrics(SCOPE) metrics_by_name: Dict[str, List[Any]] = {} - metrics_data = self.metric_reader.get_metrics_data() - resource_metrics = ( - metrics_data and metrics_data.resource_metrics - ) or [] - for resource_metric in resource_metrics: - for scope_metric in resource_metric.scope_metrics or []: - for metric in scope_metric.metrics or []: - points = metric.data.data_points or [] - metrics_by_name.setdefault(metric.name, []).extend(points) - return metrics_by_name, resource_metrics + for metric in metrics or []: + points = metric.data.data_points or [] + metrics_by_name.setdefault(metric.name, []).extend(points) + return metrics_by_name def _assert_metric_scope_schema_urls( - self, resource_metrics: List[Any], expected_schema_url: str + self, expected_schema_url: str ) -> None: - for resource_metric in resource_metrics: + for ( + resource_metric + ) in self.memory_metrics_reader.get_metrics_data().resource_metrics: for scope_metric in resource_metric.scope_metrics: + if scope_metric.scope.name != SCOPE: + continue self.assertEqual( scope_metric.scope.schema_url, expected_schema_url ) From 349ffe313cb848d4c55ab290e9e9a4565f6ab9f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Tue, 17 Mar 2026 11:22:22 -0300 Subject: [PATCH 25/78] add opentelemetry-distro to uv (#4331) Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- pyproject.toml | 8 +++-- uv.lock | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 736f1c3edf0..5980aea2eab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,10 +7,11 @@ dependencies = [ "opentelemetry-api", "opentelemetry-sdk", "opentelemetry-semantic-conventions", + "opentelemetry-instrumentation", + "opentelemetry-distro", "opentelemetry-test-utils", "opentelemetry-exporter-prometheus-remote-write", "opentelemetry-exporter-richconsole", - "opentelemetry-instrumentation", "opentelemetry-instrumentation-aio-pika[instruments]", "opentelemetry-instrumentation-aiohttp-client[instruments]", "opentelemetry-instrumentation-aiohttp-server[instruments]", @@ -80,9 +81,11 @@ opentelemetry-api = { git = "https://github.com/open-telemetry/opentelemetry-pyt opentelemetry-sdk = { git = "https://github.com/open-telemetry/opentelemetry-python", branch = "main", subdirectory = "opentelemetry-sdk" } opentelemetry-semantic-conventions = { git = "https://github.com/open-telemetry/opentelemetry-python", branch = "main", subdirectory = "opentelemetry-semantic-conventions" } opentelemetry-test-utils = { git = "https://github.com/open-telemetry/opentelemetry-python", branch = "main", subdirectory = "tests/opentelemetry-test-utils" } +opentelemetry-exporter-otlp = { git = "https://github.com/open-telemetry/opentelemetry-python", branch = "main", subdirectory = "exporter/opentelemetry-exporter-otlp" } +opentelemetry-instrumentation = { workspace = true } +opentelemetry-distro = { workspace = true } opentelemetry-exporter-prometheus-remote-write = { workspace = true } opentelemetry-exporter-richconsole = { workspace = true } -opentelemetry-instrumentation = { workspace = true } opentelemetry-instrumentation-aio-pika = { workspace = true } opentelemetry-instrumentation-aiohttp-client = { workspace = true } opentelemetry-instrumentation-aiohttp-server = { workspace = true } @@ -144,6 +147,7 @@ members = [ "instrumentation-genai/*", "exporter/*", "opentelemetry-instrumentation", + "opentelemetry-distro", "propagator/*", "util/*", ] diff --git a/uv.lock b/uv.lock index ad3f6483c78..1ffeaf9c667 100644 --- a/uv.lock +++ b/uv.lock @@ -11,6 +11,7 @@ resolution-markers = [ [manifest] members = [ + "opentelemetry-distro", "opentelemetry-exporter-credential-provider-gcp", "opentelemetry-exporter-prometheus-remote-write", "opentelemetry-exporter-richconsole", @@ -2628,6 +2629,29 @@ dependencies = [ { name = "typing-extensions" }, ] +[[package]] +name = "opentelemetry-distro" +source = { editable = "opentelemetry-distro" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-sdk" }, +] + +[package.optional-dependencies] +otlp = [ + { name = "opentelemetry-exporter-otlp" }, +] + +[package.metadata] +requires-dist = [ + { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, + { name = "opentelemetry-exporter-otlp", marker = "extra == 'otlp'", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=exporter%2Fopentelemetry-exporter-otlp&branch=main" }, + { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, + { name = "opentelemetry-sdk", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-sdk&branch=main" }, +] +provides-extras = ["otlp"] + [[package]] name = "opentelemetry-exporter-credential-provider-gcp" source = { editable = "exporter/opentelemetry-exporter-credential-provider-gcp" } @@ -2644,6 +2668,51 @@ requires-dist = [ { name = "requests", specifier = ">=2.7" }, ] +[[package]] +name = "opentelemetry-exporter-otlp" +version = "1.40.0.dev0" +source = { git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=exporter%2Fopentelemetry-exporter-otlp&branch=main#f32b684a1ccd6d5eb658ec0b45bf18928ea430e4" } +dependencies = [ + { name = "opentelemetry-exporter-otlp-proto-grpc" }, + { name = "opentelemetry-exporter-otlp-proto-http" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.40.0.dev0" +source = { git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=exporter%2Fopentelemetry-exporter-otlp-proto-common&branch=main#f32b684a1ccd6d5eb658ec0b45bf18928ea430e4" } +dependencies = [ + { name = "opentelemetry-proto" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-grpc" +version = "1.40.0.dev0" +source = { git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=exporter%2Fopentelemetry-exporter-otlp-proto-grpc&branch=main#f32b684a1ccd6d5eb658ec0b45bf18928ea430e4" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "typing-extensions" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-http" +version = "1.40.0.dev0" +source = { git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=exporter%2Fopentelemetry-exporter-otlp-proto-http&branch=main#f32b684a1ccd6d5eb658ec0b45bf18928ea430e4" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "requests" }, + { name = "typing-extensions" }, +] + [[package]] name = "opentelemetry-exporter-prometheus-remote-write" source = { editable = "exporter/opentelemetry-exporter-prometheus-remote-write" } @@ -4125,12 +4194,21 @@ requires-dist = [ { name = "opentelemetry-sdk", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-sdk&branch=main" }, ] +[[package]] +name = "opentelemetry-proto" +version = "1.40.0.dev0" +source = { git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-proto&branch=main#f32b684a1ccd6d5eb658ec0b45bf18928ea430e4" } +dependencies = [ + { name = "protobuf" }, +] + [[package]] name = "opentelemetry-python-contrib" version = "0.0.0" source = { virtual = "." } dependencies = [ { name = "opentelemetry-api" }, + { name = "opentelemetry-distro" }, { name = "opentelemetry-exporter-prometheus-remote-write" }, { name = "opentelemetry-exporter-richconsole" }, { name = "opentelemetry-instrumentation" }, @@ -4202,6 +4280,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, + { name = "opentelemetry-distro", editable = "opentelemetry-distro" }, { name = "opentelemetry-exporter-prometheus-remote-write", editable = "exporter/opentelemetry-exporter-prometheus-remote-write" }, { name = "opentelemetry-exporter-richconsole", editable = "exporter/opentelemetry-exporter-richconsole" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, From 7930a1541600c5d56b2cbb911f4349cf90548436 Mon Sep 17 00:00:00 2001 From: Lukas Hering <40302054+herin049@users.noreply.github.com> Date: Wed, 18 Mar 2026 04:27:48 -0400 Subject: [PATCH 26/78] update Lukas affiliation in README (#4342) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8de305d0917..10aae26d9a1 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ For more information about the maintainer role, see the [community repository](h - [Jeremy Voss](https://github.com/jeremydvoss), Microsoft - [Keith Decker](https://github.com/keith-decker), Cisco/Splunk - [Liudmila Molkova](https://github.com/lmolkova), Grafana Labs -- [Lukas Hering](https://github.com/herin049), Capital One +- [Lukas Hering](https://github.com/herin049), Oracle - [Owais Lone](https://github.com/owais), Splunk - [Pablo Collins](https://github.com/pmcollins), Splunk - [Sanket Mehta](https://github.com/sanketmehta28), Cisco From bd01dcd720b0a47261c939f2a136ab07d5a0f550 Mon Sep 17 00:00:00 2001 From: Juan Calvo Pozo Date: Thu, 19 Mar 2026 09:03:37 +0000 Subject: [PATCH 27/78] Fix gRPC client interceptor breaking bidirectional streaming (#1180) (#4259) * Fix gRPC client interceptor breaking bidirectional streaming (#1180) Route bidi (stream-stream) RPCs through `_intercept` instead of the generator-based `_intercept_server_stream`. The generator wrapper strips the grpc.Call/grpc.Future interface, causing downstream code (e.g. google.api_core.bidi.BidiRpc) to crash with: AttributeError: 'generator' object has no attribute 'add_done_callback' The fix adds `and not client_info.is_client_stream` to the condition in `intercept_stream()` so only unary-stream RPCs use the generator path. Includes a regression test verifying the bidi stream response preserves the grpc.Call interface (add_done_callback, cancel, is_active). Co-authored-by: Cursor * Add gRPC status code attributes to error handling in client * Remove redundant status description from span error status The gRPC status code is already captured in the RPC_GRPC_STATUS_CODE attribute, making the description in span status unnecessary. * Update CHANGELOG.md * Update CHANGELOG.md * Add RPC_GRPC_STATUS_CODE assertions to client error tests Verify that error spans include the correct gRPC status code attribute (INVALID_ARGUMENT) in both sync and async client interceptor tests. --------- Co-authored-by: Cursor Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 + .../instrumentation/grpc/_client.py | 8 ++- .../tests/test_aio_client_interceptor.py | 16 +++++ .../tests/test_client_interceptor.py | 61 +++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c4d7ebddd8..2e2eea89276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4321](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4321)) - `opentelemetry-instrumentation-logging`: Add recursion guard in LoggingHandler.emit to prevent deadlock ([#4302](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4302)) +- `opentelemetry-instrumentation-grpc`: Fix bidirectional streaming RPCs raising `AttributeError: 'generator' object has no attribute 'add_done_callback'` + ([#4259](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4259)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_client.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_client.py index bbeb4ec1d94..a9264b56f41 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_client.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_client.py @@ -60,6 +60,12 @@ def callback(response_future): code = response_future.code() if code != grpc.StatusCode.OK: rpc_info.error = code + span.set_attribute(RPC_GRPC_STATUS_CODE, code.value[0]) + span.set_status( + Status( + status_code=StatusCode.ERROR, + ) + ) return response = response_future.result() rpc_info.response = response @@ -228,7 +234,7 @@ def intercept_stream( if self._filter is not None and not self._filter(client_info): return invoker(request_or_iterator, metadata) - if client_info.is_server_stream: + if client_info.is_server_stream and not client_info.is_client_stream: return self._intercept_server_stream( request_or_iterator, metadata, client_info, invoker ) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py index 850ad796613..daa4d68dc3f 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_aio_client_interceptor.py @@ -224,6 +224,10 @@ async def test_error_simple(self): span.status.status_code, trace.StatusCode.ERROR, ) + self.assertEqual( + span.attributes[RPC_GRPC_STATUS_CODE], + grpc.StatusCode.INVALID_ARGUMENT.value[0], + ) async def test_error_unary_stream(self): with self.assertRaises(grpc.RpcError): @@ -237,6 +241,10 @@ async def test_error_unary_stream(self): span.status.status_code, trace.StatusCode.ERROR, ) + self.assertEqual( + span.attributes[RPC_GRPC_STATUS_CODE], + grpc.StatusCode.INVALID_ARGUMENT.value[0], + ) async def test_error_stream_unary(self): with self.assertRaises(grpc.RpcError): @@ -249,6 +257,10 @@ async def test_error_stream_unary(self): span.status.status_code, trace.StatusCode.ERROR, ) + self.assertEqual( + span.attributes[RPC_GRPC_STATUS_CODE], + grpc.StatusCode.INVALID_ARGUMENT.value[0], + ) async def test_error_stream_stream(self): with self.assertRaises(grpc.RpcError): @@ -264,6 +276,10 @@ async def test_error_stream_stream(self): span.status.status_code, trace.StatusCode.ERROR, ) + self.assertEqual( + span.attributes[RPC_GRPC_STATUS_CODE], + grpc.StatusCode.INVALID_ARGUMENT.value[0], + ) # pylint:disable=no-self-use async def test_client_interceptor_trace_context_propagation(self): diff --git a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py index e001d2ed57e..3830bf00c4b 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py @@ -221,6 +221,51 @@ def test_stream_stream(self): }, ) + def test_stream_stream_preserves_call_interface(self): + """Regression test for issue #1180. + + Bidirectional streaming RPCs must return an object that implements + grpc.Call (add_done_callback, cancel, is_active, etc.) rather than + a bare generator. Before the fix, bidi streams were routed through + the generator-based _intercept_server_stream, which stripped the + grpc.Call interface and caused downstream code to crash with: + AttributeError: 'generator' object has no attribute 'add_done_callback' + """ + + def request_messages(): + for _ in range(5): + yield Request(client_id=1, request_data="data") + + response_iterator = self._stub.BidirectionalStreamingMethod( + request_messages(), metadata=(("key", "value"),) + ) + + for attr in ("add_done_callback", "cancel", "is_active"): + self.assertTrue( + hasattr(response_iterator, attr), + f"bidi stream response missing grpc.Call method '{attr}'", + ) + + list(response_iterator) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + span = spans[0] + + self.assertEqual( + span.name, "/GRPCTestServer/BidirectionalStreamingMethod" + ) + self.assertIs(span.kind, trace.SpanKind.CLIENT) + self.assertSpanHasAttributes( + span, + { + RPC_METHOD: "BidirectionalStreamingMethod", + RPC_SERVICE: "GRPCTestServer", + RPC_SYSTEM: "grpc", + RPC_GRPC_STATUS_CODE: grpc.StatusCode.OK.value[0], + }, + ) + def test_error_simple(self): with self.assertRaises(grpc.RpcError): simple_method(self._stub, error=True) @@ -232,6 +277,10 @@ def test_error_simple(self): span.status.status_code, trace.StatusCode.ERROR, ) + self.assertEqual( + span.attributes[RPC_GRPC_STATUS_CODE], + grpc.StatusCode.INVALID_ARGUMENT.value[0], + ) def test_error_stream_unary(self): with self.assertRaises(grpc.RpcError): @@ -244,6 +293,10 @@ def test_error_stream_unary(self): span.status.status_code, trace.StatusCode.ERROR, ) + self.assertEqual( + span.attributes[RPC_GRPC_STATUS_CODE], + grpc.StatusCode.INVALID_ARGUMENT.value[0], + ) def test_error_unary_stream(self): with self.assertRaises(grpc.RpcError): @@ -256,6 +309,10 @@ def test_error_unary_stream(self): span.status.status_code, trace.StatusCode.ERROR, ) + self.assertEqual( + span.attributes[RPC_GRPC_STATUS_CODE], + grpc.StatusCode.INVALID_ARGUMENT.value[0], + ) def test_error_stream_stream(self): with self.assertRaises(grpc.RpcError): @@ -268,6 +325,10 @@ def test_error_stream_stream(self): span.status.status_code, trace.StatusCode.ERROR, ) + self.assertEqual( + span.attributes[RPC_GRPC_STATUS_CODE], + grpc.StatusCode.INVALID_ARGUMENT.value[0], + ) def test_client_interceptor_falsy_response( self, From 6d3bbfbfcd3da1fd416af230a135db74bc9367f5 Mon Sep 17 00:00:00 2001 From: Lukas Hering <40302054+herin049@users.noreply.github.com> Date: Thu, 19 Mar 2026 05:08:09 -0400 Subject: [PATCH 28/78] feat: add support for aiobotocore instrumentation (#4049) * initial implementation for aiobotocore instrumentation * fix failing tests * add basic set of tests for aiobotocore instrumentation * update CHANGELOG.md * address comments and update tests to run with and without aiobotocore installed * update workflows and fix lock file * update tests * fix lint * Update botocore documentation to include aiobotocore * update bootstrap_gen.py * update botocore instrumentation test deps * update uv.lock * fix CHANGELOG.md and remove unused variable in tests --------- Co-authored-by: Riccardo Magliocchetti --- .github/workflows/core_contrib_test_0.yml | 60 +++ .github/workflows/test_0.yml | 456 ++++++++--------- .github/workflows/test_1.yml | 456 ++++++++--------- .github/workflows/test_2.yml | 456 ++++++++--------- .github/workflows/test_3.yml | 228 +++++++++ CHANGELOG.md | 2 + instrumentation/README.md | 2 +- .../README.rst | 8 +- .../pyproject.toml | 5 +- .../instrumentation/botocore/__init__.py | 347 ++++++++----- .../botocore/extensions/__init__.py | 34 +- .../botocore/extensions/registry.py | 216 ++++++++ .../instrumentation/botocore/package.py | 5 +- .../instrumentation/botocore/utils.py | 15 + .../test-requirements-2.txt | 40 ++ .../test-requirements-3.txt | 40 ++ .../tests/test_aiobotocore_instrumentation.py | 460 ++++++++++++++++++ .../tests/test_botocore_instrumentation.py | 36 +- .../instrumentation/bootstrap_gen.py | 4 + pyproject.toml | 2 +- tox.ini | 6 +- uv.lock | 57 ++- 22 files changed, 2085 insertions(+), 850 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/registry.py create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/test-requirements-2.txt create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/test-requirements-3.txt create mode 100644 instrumentation/opentelemetry-instrumentation-botocore/tests/test_aiobotocore_instrumentation.py diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test_0.yml index 019d2327e2a..3f312768732 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test_0.yml @@ -777,6 +777,66 @@ jobs: - name: Run tests run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra + py39-test-instrumentation-botocore-2: + name: instrumentation-botocore-2 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-2 -- -ra + + py39-test-instrumentation-botocore-3: + name: instrumentation-botocore-3 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-3 -- -ra + py39-test-instrumentation-boto3sqs: name: instrumentation-boto3sqs runs-on: ubuntu-latest diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml index eeae3918222..fd5a9c4fab3 100644 --- a/.github/workflows/test_0.yml +++ b/.github/workflows/test_0.yml @@ -3451,6 +3451,234 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-botocore-1-wrapt2 -- -ra + py39-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-2 -- -ra + + py39-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-3 -- -ra + + py310-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-2 -- -ra + + py310-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-3 -- -ra + + py311-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-2 -- -ra + + py311-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-3 -- -ra + + py312-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-2 -- -ra + + py312-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-3 -- -ra + + py313-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-2 -- -ra + + py313-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-3 -- -ra + + py314-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-botocore-2 -- -ra + + py314-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-botocore-3 -- -ra + py39-test-instrumentation-boto3sqs_ubuntu-latest: name: instrumentation-boto3sqs 3.9 Ubuntu runs-on: ubuntu-latest @@ -4552,231 +4780,3 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra - - py312-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra - - py313-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-0 -- -ra - - py313-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-1 -- -ra - - py313-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-2 -- -ra - - py314-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-0 -- -ra - - py314-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-1 -- -ra - - py314-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-2 -- -ra - - pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra - - pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra - - pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra - - py39-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra - - py39-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml index 585c331a906..1b0cd014d7e 100644 --- a/.github/workflows/test_1.yml +++ b/.github/workflows/test_1.yml @@ -31,6 +31,234 @@ env: jobs: + py312-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra + + py313-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-0 -- -ra + + py313-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-1 -- -ra + + py313-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-2 -- -ra + + py314-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-elasticsearch-0 -- -ra + + py314-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-elasticsearch-1 -- -ra + + py314-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-elasticsearch-2 -- -ra + + pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra + + pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra + + pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra + + py39-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-0 -- -ra + + py39-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-1 -- -ra + py39-test-instrumentation-falcon-2_ubuntu-latest: name: instrumentation-falcon-2 3.9 Ubuntu runs-on: ubuntu-latest @@ -4552,231 +4780,3 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-asyncpg-wrapt2 -- -ra - - py313-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-asyncpg-wrapt1 -- -ra - - py313-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-asyncpg-wrapt2 -- -ra - - py314-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-asyncpg-wrapt1 -- -ra - - py314-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-asyncpg-wrapt2 -- -ra - - py39-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlite3 -- -ra - - py310-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-sqlite3 -- -ra - - py311-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-sqlite3 -- -ra - - py312-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-sqlite3 -- -ra - - py313-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-sqlite3 -- -ra - - py314-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-sqlite3 -- -ra - - pypy3-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra - - py39-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml index b80cf7400e9..00c4a1a0a6e 100644 --- a/.github/workflows/test_2.yml +++ b/.github/workflows/test_2.yml @@ -31,6 +31,234 @@ env: jobs: + py313-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-asyncpg-wrapt1 -- -ra + + py313-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-asyncpg-wrapt2 -- -ra + + py314-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-asyncpg-wrapt1 -- -ra + + py314-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-asyncpg-wrapt2 -- -ra + + py39-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sqlite3 -- -ra + + py310-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sqlite3 -- -ra + + py311-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-sqlite3 -- -ra + + py312-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-sqlite3 -- -ra + + py313-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-sqlite3 -- -ra + + py314-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-sqlite3 -- -ra + + pypy3-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra + + py39-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-wsgi -- -ra + py310-test-instrumentation-wsgi_ubuntu-latest: name: instrumentation-wsgi 3.10 Ubuntu runs-on: ubuntu-latest @@ -4552,231 +4780,3 @@ jobs: - name: Run tests run: tox -e py310-test-instrumentation-cassandra-driver -- -ra - - py310-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-cassandra-scylla -- -ra - - py311-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-cassandra-driver -- -ra - - py311-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-cassandra-scylla -- -ra - - py312-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-cassandra-driver -- -ra - - py312-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-cassandra-scylla -- -ra - - py313-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-cassandra-driver -- -ra - - py313-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-cassandra-scylla -- -ra - - py314-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-cassandra-driver -- -ra - - py314-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra - - pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra - - py39-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra - - py310-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-processor-baggage -- -ra diff --git a/.github/workflows/test_3.yml b/.github/workflows/test_3.yml index 4fbfa25749c..d52c3a98a12 100644 --- a/.github/workflows/test_3.yml +++ b/.github/workflows/test_3.yml @@ -31,6 +31,234 @@ env: jobs: + py310-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-cassandra-scylla -- -ra + + py311-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-cassandra-driver -- -ra + + py311-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-cassandra-scylla -- -ra + + py312-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-cassandra-driver -- -ra + + py312-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-cassandra-scylla -- -ra + + py313-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-cassandra-driver -- -ra + + py313-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-cassandra-scylla -- -ra + + py314-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-cassandra-driver -- -ra + + py314-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra + + pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra + + py39-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-processor-baggage -- -ra + + py310-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-processor-baggage -- -ra + py311-test-processor-baggage_ubuntu-latest: name: processor-baggage 3.11 Ubuntu runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e2eea89276..8d3dcff52a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4203](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4203)) - `opentelemetry-instrumentation-psycopg2`: Add parameter `capture_parameters` to instrumentor. ([#4212](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4212)) +- `opentelemetry-instrumentation-botocore`: Add support for instrumenting `aiobotocore` + ([#4049](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4049)) ### Fixed diff --git a/instrumentation/README.md b/instrumentation/README.md index e9a727d29b7..2802d8a872d 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -12,7 +12,7 @@ | [opentelemetry-instrumentation-asyncpg](./opentelemetry-instrumentation-asyncpg) | asyncpg >= 0.12.0 | No | development | [opentelemetry-instrumentation-aws-lambda](./opentelemetry-instrumentation-aws-lambda) | aws_lambda | No | development | [opentelemetry-instrumentation-boto3sqs](./opentelemetry-instrumentation-boto3sqs) | boto3 ~= 1.0 | No | development -| [opentelemetry-instrumentation-botocore](./opentelemetry-instrumentation-botocore) | botocore ~= 1.0 | No | development +| [opentelemetry-instrumentation-botocore](./opentelemetry-instrumentation-botocore) | botocore~=1.0,aiobotocore~=2.0 | No | development | [opentelemetry-instrumentation-cassandra](./opentelemetry-instrumentation-cassandra) | cassandra-driver ~= 3.25,scylla-driver ~= 3.25 | No | development | [opentelemetry-instrumentation-celery](./opentelemetry-instrumentation-celery) | celery >= 4.0, < 6.0 | No | development | [opentelemetry-instrumentation-click](./opentelemetry-instrumentation-click) | click >= 8.1.3, < 9.0.0 | No | development diff --git a/instrumentation/opentelemetry-instrumentation-botocore/README.rst b/instrumentation/opentelemetry-instrumentation-botocore/README.rst index 5b70922e078..61804f740bb 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/README.rst +++ b/instrumentation/opentelemetry-instrumentation-botocore/README.rst @@ -6,7 +6,7 @@ OpenTelemetry Botocore Tracing .. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-botocore.svg :target: https://pypi.org/project/opentelemetry-instrumentation-botocore/ -This library allows tracing requests made by the Botocore library. +This library allows tracing requests made by the botocore and aiobotocore libraries. Extensions ---------- @@ -14,14 +14,14 @@ Extensions The instrumentation supports creating extensions for AWS services for enriching what is collected. We have extensions for the following AWS services: -- Bedrock Runtime +- Bedrock Runtime (botocore only) - DynamoDB - Lambda - SNS - SQS -Bedrock Runtime -*************** +Bedrock Runtime (botocore only) +******************************* This extension implements the GenAI semantic conventions for the following API calls: diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index fb64bb46d71..00cab57e778 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -34,12 +34,15 @@ dependencies = [ ] [project.optional-dependencies] -instruments = [ +instruments = [] +instruments-any = [ "botocore ~= 1.0", + "aiobotocore ~= 2.0", ] [project.entry-points.opentelemetry_instrumentor] botocore = "opentelemetry.instrumentation.botocore:BotocoreInstrumentor" +aiobotocore = "opentelemetry.instrumentation.botocore:AiobotocoreInstrumentor" [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-botocore" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py index 6fd42d6ab4a..fb9074d1938 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py @@ -13,14 +13,15 @@ # limitations under the License. """ -Instrument `Botocore`_ to trace service requests. +Instrument `botocore`_ and `aiobotocore`_ to trace service requests. There are two options for instrumenting code. The first option is to use the ``opentelemetry-instrument`` executable which will automatically -instrument your Botocore client. The second is to programmatically enable +instrument your botocore or aiobotocore client. The second is to programmatically enable instrumentation via the following code: -.. _Botocore: https://pypi.org/project/botocore/ +.. _botocore: https://pypi.org/project/botocore/ +.. _aiobotocore: https://pypi.org/project/aiobotocore/ Usage ----- @@ -31,10 +32,10 @@ import botocore.session - # Instrument Botocore + # Instrument botocore BotocoreInstrumentor().instrument() - # This will create a span with Botocore-specific attributes + # This will create a span with botocore-specific attributes session = botocore.session.get_session() session.set_credentials( access_key="access-key", secret_key="secret-key" @@ -42,6 +43,27 @@ ec2 = session.create_client("ec2", region_name="us-west-2") ec2.describe_instances() +Async Usage +----------- + +.. code:: python + + from opentelemetry.instrumentation.botocore import AiobotocoreInstrumentor + import aiobotocore.session + import asyncio + + + async def main(): + # Instrument Aiobotocore + AiobotocoreInstrumentor().instrument() + + # This will create a span with aiobotocore-specific attributes + session = aiobotocore.session.get_session() + async with session.create_client("ec2") as client: + await client.describe_instances() + + asyncio.run(main()) + Thread Context Propagation -------------------------- @@ -63,7 +85,7 @@ API --- -The `instrument` method accepts the following keyword args: +The `instrument` method (for both ``BotocoreInstrumentor`` and ``AiobotocoreInstrumentor``) accepts the following keyword args: * tracer_provider (``TracerProvider``) - an optional tracer provider * request_hook (``Callable[[Span, str, str, dict], None]``) - a function with extra user-defined logic to be performed before performing the request @@ -84,10 +106,10 @@ def response_hook(span, service_name, operation_name, result): # response hook logic pass - # Instrument Botocore with hooks + # Instrument botocore with hooks BotocoreInstrumentor().instrument(request_hook=request_hook, response_hook=response_hook) - # This will create a span with Botocore-specific attributes, including custom attributes added from the hooks + # This will create a span with botocore-specific attributes, including custom attributes added from the hooks session = botocore.session.get_session() session.set_credentials( access_key="access-key", secret_key="secret-key" @@ -97,34 +119,42 @@ def response_hook(span, service_name, operation_name, result): """ import logging -from typing import Any, Callable, Collection, Dict, Optional, Tuple +from typing import Any, Collection, Dict, Optional, Tuple from botocore.client import BaseClient from botocore.endpoint import Endpoint from botocore.exceptions import ClientError from wrapt import wrap_function_wrapper -from opentelemetry._logs import get_logger from opentelemetry.instrumentation.botocore.extensions import ( - _find_extension, - _has_extension, + _AIOBOTOCORE_EXTENSIONS, + _BOTOCORE_EXTENSIONS, +) +from opentelemetry.instrumentation.botocore.extensions.registry import ( + ExtensionRegistry, ) from opentelemetry.instrumentation.botocore.extensions.types import ( _AwsSdkCallContext, - _AwsSdkExtension, _BotocoreInstrumentorContext, ) -from opentelemetry.instrumentation.botocore.package import _instruments -from opentelemetry.instrumentation.botocore.utils import get_server_attributes -from opentelemetry.instrumentation.botocore.version import __version__ +from opentelemetry.instrumentation.botocore.package import ( + _instruments_aiobotocore, + _instruments_botocore, +) +from opentelemetry.instrumentation.botocore.utils import ( + _safe_invoke, + get_server_attributes, +) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.utils import ( is_instrumentation_enabled, suppress_http_instrumentation, unwrap, ) -from opentelemetry.metrics import Instrument, Meter, get_meter -from opentelemetry.propagators.aws.aws_xray_propagator import AwsXRayPropagator +from opentelemetry.propagators.aws.aws_xray_propagator import ( + TRACE_HEADER_KEY, + AwsXRayPropagator, +) from opentelemetry.semconv._incubating.attributes.cloud_attributes import ( CLOUD_REGION, ) @@ -136,7 +166,6 @@ def response_hook(span, service_name, operation_name, result): RPC_SERVICE, RPC_SYSTEM, ) -from opentelemetry.trace import get_tracer from opentelemetry.trace.span import Span logger = logging.getLogger(__name__) @@ -150,25 +179,20 @@ class BotocoreInstrumentor(BaseInstrumentor): def __init__(self): super().__init__() - self.request_hook = None - self.response_hook = None - self.propagator = AwsXRayPropagator() + if not hasattr(self, "request_hook"): + self.request_hook = None + if not hasattr(self, "response_hook"): + self.response_hook = None + if not hasattr(self, "extension_registry"): + self.extension_registry = None + if not hasattr(self, "propagator"): + self.propagator = AwsXRayPropagator() def instrumentation_dependencies(self) -> Collection[str]: - return _instruments + return _instruments_botocore def _instrument(self, **kwargs): # pylint: disable=attribute-defined-outside-init - - # tracers are lazy initialized per-extension in _get_tracer - self._tracers = {} - # loggers are lazy initialized per-extension in _get_logger - self._loggers = {} - # meters are lazy initialized per-extension in _get_meter - self._meters = {} - # metrics are lazy initialized per-extension in _get_metrics - self._metrics: Dict[str, Dict[str, Instrument]] = {} - self.request_hook = kwargs.get("request_hook") self.response_hook = kwargs.get("response_hook") @@ -176,9 +200,13 @@ def _instrument(self, **kwargs): if propagator is not None: self.propagator = propagator - self.tracer_provider = kwargs.get("tracer_provider") - self.logger_provider = kwargs.get("logger_provider") - self.meter_provider = kwargs.get("meter_provider") + self.extension_registry = ExtensionRegistry( + __name__, + _BOTOCORE_EXTENSIONS, + kwargs.get("tracer_provider"), + kwargs.get("logger_provider"), + kwargs.get("meter_provider"), + ) wrap_function_wrapper( "botocore.client", @@ -192,84 +220,168 @@ def _instrument(self, **kwargs): self._patched_endpoint_prepare_request, ) - @staticmethod - def _get_instrumentation_name(extension: _AwsSdkExtension) -> str: - has_extension = _has_extension(extension._call_context) - return ( - f"{__name__}.{extension._call_context.service}" - if has_extension - else __name__ + def _uninstrument(self, **kwargs): + unwrap(BaseClient, "_make_api_call") + unwrap(Endpoint, "prepare_request") + + # pylint: disable=unused-argument + def _patched_endpoint_prepare_request( + self, wrapped, instance, args, kwargs + ): + request = args[0] + headers = request.headers + + # There may be situations where both Botocore and Aiobotocore are + # instrumented at the same time. To avoid double-injection of headers, + # we add a check to see if the header is already present. If it is, + # we skip injection. + if TRACE_HEADER_KEY in headers: + return wrapped(*args, **kwargs) + + # Only the x-ray header is propagated by AWS services. Using any + # other propagator will lose the trace context. + self.propagator.inject(headers) + + return wrapped(*args, **kwargs) + + # pylint: disable=too-many-branches + def _patched_api_call(self, original_func, instance, args, kwargs): + if not is_instrumentation_enabled(): + return original_func(*args, **kwargs) + + call_context = _determine_call_context(instance, args) + if call_context is None: + return original_func(*args, **kwargs) + + extension = self.extension_registry.get_extension(call_context) + if not extension.should_trace_service_call(): + return original_func(*args, **kwargs) + + attributes = { + RPC_SYSTEM: "aws-api", + RPC_SERVICE: call_context.service_id, + RPC_METHOD: call_context.operation, + CLOUD_REGION: call_context.region, + **get_server_attributes(call_context.endpoint_url), + } + + _safe_invoke(extension.extract_attributes, attributes) + end_span_on_exit = extension.should_end_span_on_exit() + + tracer = self.extension_registry.get_tracer(extension) + metrics = self.extension_registry.get_metrics(extension) + instrumentor_ctx = _BotocoreInstrumentorContext( + logger=self.extension_registry.get_logger(extension), + metrics=metrics, ) + with tracer.start_as_current_span( + call_context.span_name, + kind=call_context.span_kind, + attributes=attributes, + # tracing streaming services require to close the span manually + # at a later time after the stream has been consumed + end_on_exit=end_span_on_exit, + ) as span: + _safe_invoke(extension.before_service_call, span, instrumentor_ctx) + self._call_request_hook(span, call_context) - def _get_tracer(self, extension: _AwsSdkExtension): - """This is a multiplexer in order to have a tracer per extension""" + try: + with suppress_http_instrumentation(): + result = None + try: + result = original_func(*args, **kwargs) + except ClientError as error: + result = getattr(error, "response", None) + _apply_response_attributes(span, result) + _safe_invoke( + extension.on_error, span, error, instrumentor_ctx + ) + raise + _apply_response_attributes(span, result) + _safe_invoke( + extension.on_success, span, result, instrumentor_ctx + ) + finally: + _safe_invoke(extension.after_service_call, instrumentor_ctx) + self._call_response_hook(span, call_context, result) - instrumentation_name = self._get_instrumentation_name(extension) - tracer = self._tracers.get(instrumentation_name) - if tracer: - return tracer + return result - schema_version = extension.tracer_schema_version() - self._tracers[instrumentation_name] = get_tracer( - instrumentation_name, - __version__, - self.tracer_provider, - schema_url=f"https://opentelemetry.io/schemas/{schema_version}", + def _call_request_hook(self, span: Span, call_context: _AwsSdkCallContext): + if not callable(self.request_hook): + return + self.request_hook( + span, + call_context.service, + call_context.operation, + call_context.params, ) - return self._tracers[instrumentation_name] - - def _get_logger(self, extension: _AwsSdkExtension): - """This is a multiplexer in order to have a logger per extension""" - - instrumentation_name = self._get_instrumentation_name(extension) - instrumentation_logger = self._loggers.get(instrumentation_name) - if instrumentation_logger: - return instrumentation_logger - - schema_version = extension.event_logger_schema_version() - self._loggers[instrumentation_name] = get_logger( - instrumentation_name, - "", - schema_url=f"https://opentelemetry.io/schemas/{schema_version}", - logger_provider=self.logger_provider, + + def _call_response_hook( + self, span: Span, call_context: _AwsSdkCallContext, result + ): + if not callable(self.response_hook): + return + self.response_hook( + span, call_context.service, call_context.operation, result ) - return self._loggers[instrumentation_name] - def _get_meter(self, extension: _AwsSdkExtension): - """This is a multiplexer in order to have a meter per extension""" +class AiobotocoreInstrumentor(BaseInstrumentor): + """An instrumentor for Aiobotocore. - instrumentation_name = self._get_instrumentation_name(extension) - meter = self._meters.get(instrumentation_name) - if meter: - return meter + See `BaseInstrumentor` + """ - schema_version = extension.meter_schema_version() - self._meters[instrumentation_name] = get_meter( - instrumentation_name, - "", - schema_url=f"https://opentelemetry.io/schemas/{schema_version}", - meter_provider=self.meter_provider, - ) + def __init__(self): + super().__init__() + if not hasattr(self, "request_hook"): + self.request_hook = None + if not hasattr(self, "response_hook"): + self.response_hook = None + if not hasattr(self, "extension_registry"): + self.extension_registry = None + if not hasattr(self, "propagator"): + self.propagator = AwsXRayPropagator() + + def instrumentation_dependencies(self) -> Collection[str]: + return _instruments_aiobotocore + + def _instrument(self, **kwargs): + # Verify that aiobotocore is present + # pylint: disable-next=import-outside-toplevel, unused-import + import aiobotocore.client # noqa: PLC0415, F401 + + # pylint: disable=attribute-defined-outside-init + self.request_hook = kwargs.get("request_hook") + self.response_hook = kwargs.get("response_hook") - return self._meters[instrumentation_name] + propagator = kwargs.get("propagator") + if propagator is not None: + self.propagator = propagator - def _get_metrics( - self, extension: _AwsSdkExtension, meter: Meter - ) -> Dict[str, Instrument]: - """This is a multiplexer for lazy initialization of metrics required by extensions""" - instrumentation_name = self._get_instrumentation_name(extension) - metrics = self._metrics.get(instrumentation_name) - if metrics is not None: - return metrics + self.extension_registry = ExtensionRegistry( + __name__, + _AIOBOTOCORE_EXTENSIONS, + kwargs.get("tracer_provider"), + kwargs.get("logger_provider"), + kwargs.get("meter_provider"), + ) - self._metrics.setdefault(instrumentation_name, {}) - metrics = self._metrics[instrumentation_name] - _safe_invoke(extension.setup_metrics, meter, metrics) - return metrics + wrap_function_wrapper( + "aiobotocore.client", + "AioBaseClient._make_api_call", + self._patched_api_call, + ) + + wrap_function_wrapper( + "botocore.endpoint", + "Endpoint.prepare_request", + self._patched_endpoint_prepare_request, + ) def _uninstrument(self, **kwargs): - unwrap(BaseClient, "_make_api_call") + unwrap("aiobotocore.client.AioBaseClient", "_make_api_call") unwrap(Endpoint, "prepare_request") # pylint: disable=unused-argument @@ -279,6 +391,13 @@ def _patched_endpoint_prepare_request( request = args[0] headers = request.headers + # There may be situations where both Botocore and Aiobotocore are + # instrumented at the same time. To avoid double-injection of headers, + # we add a check to see if the header is already present. If it is, + # we skip injection. + if TRACE_HEADER_KEY in headers: + return wrapped(*args, **kwargs) + # Only the x-ray header is propagated by AWS services. Using any # other propagator will lose the trace context. self.propagator.inject(headers) @@ -286,17 +405,17 @@ def _patched_endpoint_prepare_request( return wrapped(*args, **kwargs) # pylint: disable=too-many-branches - def _patched_api_call(self, original_func, instance, args, kwargs): + async def _patched_api_call(self, original_func, instance, args, kwargs): if not is_instrumentation_enabled(): - return original_func(*args, **kwargs) + return await original_func(*args, **kwargs) call_context = _determine_call_context(instance, args) if call_context is None: - return original_func(*args, **kwargs) + return await original_func(*args, **kwargs) - extension = _find_extension(call_context) + extension = self.extension_registry.get_extension(call_context) if not extension.should_trace_service_call(): - return original_func(*args, **kwargs) + return await original_func(*args, **kwargs) attributes = { RPC_SYSTEM: "aws-api", @@ -309,11 +428,10 @@ def _patched_api_call(self, original_func, instance, args, kwargs): _safe_invoke(extension.extract_attributes, attributes) end_span_on_exit = extension.should_end_span_on_exit() - tracer = self._get_tracer(extension) - meter = self._get_meter(extension) - metrics = self._get_metrics(extension, meter) + tracer = self.extension_registry.get_tracer(extension) + metrics = self.extension_registry.get_metrics(extension) instrumentor_ctx = _BotocoreInstrumentorContext( - logger=self._get_logger(extension), + logger=self.extension_registry.get_logger(extension), metrics=metrics, ) with tracer.start_as_current_span( @@ -331,7 +449,7 @@ def _patched_api_call(self, original_func, instance, args, kwargs): with suppress_http_instrumentation(): result = None try: - result = original_func(*args, **kwargs) + result = await original_func(*args, **kwargs) except ClientError as error: result = getattr(error, "response", None) _apply_response_attributes(span, result) @@ -418,14 +536,3 @@ def _determine_call_context( # extracting essential attributes ('service' and 'operation') failed. logger.error("Error when initializing call context", exc_info=ex) return None - - -def _safe_invoke(function: Callable, *args): - function_name = "" - try: - function_name = function.__name__ - function(*args) - except Exception as ex: # pylint:disable=broad-except - logger.error( - "Error when invoking function '%s'", function_name, exc_info=ex - ) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py index dd8ba24e9f6..feffa340982 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py @@ -15,11 +15,6 @@ import importlib import logging -from opentelemetry.instrumentation.botocore.extensions.types import ( - _AwsSdkCallContext, - _AwsSdkExtension, -) - _logger = logging.getLogger(__name__) @@ -31,7 +26,7 @@ def loader(): return loader -_KNOWN_EXTENSIONS = { +_BOTOCORE_EXTENSIONS = { "bedrock-runtime": _lazy_load(".bedrock", "_BedrockRuntimeExtension"), "dynamodb": _lazy_load(".dynamodb", "_DynamoDbExtension"), "lambda": _lazy_load(".lmbd", "_LambdaExtension"), @@ -43,19 +38,14 @@ def loader(): "sqs": _lazy_load(".sqs", "_SqsExtension"), } - -def _has_extension(call_context: _AwsSdkCallContext) -> bool: - return call_context.service in _KNOWN_EXTENSIONS - - -def _find_extension(call_context: _AwsSdkCallContext) -> _AwsSdkExtension: - try: - loader = _KNOWN_EXTENSIONS.get(call_context.service) - if loader is None: - return _AwsSdkExtension(call_context) - - extension_cls = loader() - return extension_cls(call_context) - except Exception as ex: # pylint: disable=broad-except - _logger.error("Error when loading extension: %s", ex) - return _AwsSdkExtension(call_context) +_AIOBOTOCORE_EXTENSIONS = { + # TODO: Add Bedrock support for aiobotocore + "dynamodb": _lazy_load(".dynamodb", "_DynamoDbExtension"), + "lambda": _lazy_load(".lmbd", "_LambdaExtension"), + "secretsmanager": _lazy_load( + ".secretsmanager", "_SecretsManagerExtension" + ), + "stepfunctions": _lazy_load(".sfns", "_StepFunctionsExtension"), + "sns": _lazy_load(".sns", "_SnsExtension"), + "sqs": _lazy_load(".sqs", "_SqsExtension"), +} diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/registry.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/registry.py new file mode 100644 index 00000000000..5f285dd3119 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/registry.py @@ -0,0 +1,216 @@ +# 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 __future__ import annotations + +import logging +from typing import TYPE_CHECKING, Callable, Mapping, Optional + +from opentelemetry._logs import get_logger +from opentelemetry.instrumentation.botocore.extensions.types import ( + _AwsSdkCallContext, + _AwsSdkExtension, +) +from opentelemetry.instrumentation.botocore.utils import _safe_invoke +from opentelemetry.instrumentation.botocore.version import __version__ +from opentelemetry.metrics import get_meter +from opentelemetry.trace import get_tracer + +if TYPE_CHECKING: + from opentelemetry._logs import Logger, LoggerProvider + from opentelemetry.metrics import Instrument, Meter, MeterProvider + from opentelemetry.trace import Tracer, TracerProvider + + +_logger = logging.getLogger(__name__) + + +class ExtensionRegistry: + """ + Registry for AWS SDK extensions that manages extension lookup and + associated OpenTelemetry instrumentation components (tracers, loggers, meters, metrics). + """ + + def __init__( + self, + package_name: str, + extensions: Mapping[str, Callable[[], type[_AwsSdkExtension]]], + tracer_provider: Optional[TracerProvider] = None, + logger_provider: Optional[LoggerProvider] = None, + meter_provider: Optional[MeterProvider] = None, + ): + self._package_name = package_name + self._extensions: Mapping[ + str, Callable[[], type[_AwsSdkExtension]] + ] = extensions + self._tracer_provider: TracerProvider = tracer_provider + self._logger_provider: LoggerProvider = logger_provider + self._meter_provider: MeterProvider = meter_provider + self._tracers: dict[str, Tracer] = {} + self._loggers: dict[str, Logger] = {} + self._meters: dict[str, Meter] = {} + self._metrics: dict[str, dict[str, Instrument]] = {} + + def get_extension( + self, call_context: _AwsSdkCallContext + ) -> _AwsSdkExtension: + """ + Get the appropriate extension for a given call context. + + Args: + call_context: The AWS SDK call context + + Returns: + The matching extension for the service/operation + """ + try: + loader: Callable[[], type[_AwsSdkExtension]] = ( + self._extensions.get(call_context.service) + ) + if loader is None: + return _AwsSdkExtension(call_context) + extension_cls = loader() + return extension_cls(call_context) + except Exception as exc: # pylint: disable=broad-except + _logger.error("Error when loading extension: %s", exc) + return _AwsSdkExtension(call_context) + + def has_extension(self, call_context: _AwsSdkCallContext) -> bool: + """ + Check if a dedicated extension exists for the given call context. + + Args: + call_context: The AWS SDK call context + + Returns: + True if a service-specific extension exists, False otherwise + """ + return call_context.service in self._extensions + + def get_instrumentation_name(self, extension: _AwsSdkExtension) -> str: + """ + Get the instrumentation name for an extension. + + Service-specific extensions get a namespaced name (e.g., 'module.s3'), + while the default extension uses just the module name. + + Args: + extension: The AWS SDK extension + + Returns: + The instrumentation name string + """ + if self.has_extension(extension._call_context): + return f"{self._package_name}.{extension._call_context.service}" + return self._package_name + + def get_tracer(self, extension: _AwsSdkExtension) -> Tracer: + """ + Get or create a tracer for the given extension. + + Tracers are cached per instrumentation name for reuse. + + Args: + extension: The AWS SDK extension + + Returns: + A configured Tracer instance + """ + instrumentation_name: str = self.get_instrumentation_name(extension) + if instrumentation_name in self._tracers: + return self._tracers[instrumentation_name] + + schema_version: str = extension.tracer_schema_version() + tracer: Tracer = get_tracer( + instrumentation_name, + __version__, + self._tracer_provider, + schema_url=f"https://opentelemetry.io/schemas/{schema_version}", + ) + self._tracers[instrumentation_name] = tracer + return tracer + + def get_logger(self, extension: _AwsSdkExtension): + """ + Get or create a logger for the given extension. + + Loggers are cached per instrumentation name for reuse. + + Args: + extension: The AWS SDK extension + + Returns: + A configured Logger instance + """ + instrumentation_name: str = self.get_instrumentation_name(extension) + if instrumentation_name in self._loggers: + return self._loggers[instrumentation_name] + + schema_version: str = extension.event_logger_schema_version() + logger: Logger = get_logger( + instrumentation_name, + schema_url=f"https://opentelemetry.io/schemas/{schema_version}", + logger_provider=self._logger_provider, + ) + self._loggers[instrumentation_name] = logger + return logger + + def get_meter(self, extension: _AwsSdkExtension) -> Meter: + """ + Get or create a meter for the given extension. + + Meters are cached per instrumentation name for reuse. + + Args: + extension: The AWS SDK extension + + Returns: + A configured Meter instance + """ + instrumentation_name: str = self.get_instrumentation_name(extension) + if instrumentation_name in self._meters: + return self._meters[instrumentation_name] + + schema_version: str = extension.meter_schema_version() + meter = get_meter( + instrumentation_name, + "", + schema_url=f"https://opentelemetry.io/schemas/{schema_version}", + meter_provider=self._meter_provider, + ) + self._meters[instrumentation_name] = meter + return meter + + def get_metrics( + self, extension: _AwsSdkExtension + ) -> dict[str, Instrument]: + """ + Get or create metrics for the given extension. + + Metrics are lazily initialized by calling the extension's setup_metrics method. + + Args: + extension: The AWS SDK extension + + Returns: + A dictionary mapping metric names to Instrument instances + """ + instrumentation_name: str = self.get_instrumentation_name(extension) + if instrumentation_name in self._metrics: + return self._metrics[instrumentation_name] + + meter: Meter = self.get_meter(extension) + metrics: dict[str, Instrument] = {} + _safe_invoke(extension.setup_metrics, meter, metrics) + self._metrics[instrumentation_name] = metrics + return metrics diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/package.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/package.py index a06b9c206bc..13b44a7b7d8 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/package.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/package.py @@ -12,5 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +_instruments_botocore = ("botocore~=1.0",) +_instruments_aiobotocore = ("aiobotocore~=2.0",) -_instruments = ("botocore ~= 1.0",) +_instruments = () +_instruments_any = (*_instruments_botocore, *_instruments_aiobotocore) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/utils.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/utils.py index 4309e6e9bd1..29e8d12b88f 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/utils.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/utils.py @@ -13,6 +13,8 @@ # limitations under the License. from __future__ import annotations +import logging +from typing import Callable from urllib.parse import urlparse from opentelemetry.semconv._incubating.attributes import ( @@ -20,6 +22,8 @@ ) from opentelemetry.util.types import AttributeValue +_logger = logging.getLogger(__name__) + def get_server_attributes(endpoint_url: str) -> dict[str, AttributeValue]: """Extract server.* attributes from AWS endpoint URL.""" @@ -29,3 +33,14 @@ def get_server_attributes(endpoint_url: str) -> dict[str, AttributeValue]: attributes[ServerAttributes.SERVER_ADDRESS] = parsed.hostname attributes[ServerAttributes.SERVER_PORT] = parsed.port or 443 return attributes + + +def _safe_invoke(function: Callable, *args): + function_name = "" + try: + function_name = function.__name__ + function(*args) + except Exception as ex: # pylint:disable=broad-except + _logger.error( + "Error when invoking function '%s'", function_name, exc_info=ex + ) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-2.txt new file mode 100644 index 00000000000..69dc82bdfa8 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-2.txt @@ -0,0 +1,40 @@ +asgiref==3.8.1 +aws-xray-sdk==2.12.1 +boto3==1.29.4 +botocore==1.32.4 +aiobotocore==2.8.0 +certifi==2024.7.4 +cffi==1.17.0 +charset-normalizer==3.3.2 +cryptography==43.0.1 +Deprecated==1.2.14 +docker==7.0.0 +idna==3.7 +iniconfig==2.0.0 +Jinja2==3.1.6 +jmespath==1.0.1 +MarkupSafe==2.1.5 +moto==5.1.11 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pycparser==2.21 +pytest==7.4.4 +pytest-vcr==1.0.2 +python-dateutil==2.8.2 +pytz==2024.1 +PyYAML==6.0.1 +requests==2.32.3 +responses==0.25.0 +s3transfer==0.7.0 +six==1.16.0 +tomli==2.0.1 +typing_extensions==4.12.2 +urllib3==1.26.19 +Werkzeug==3.0.6 +wrapt==1.16.0 +xmltodict==0.13.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e propagator/opentelemetry-propagator-aws-xray +-e instrumentation/opentelemetry-instrumentation-botocore diff --git a/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-3.txt b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-3.txt new file mode 100644 index 00000000000..518da691cc7 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-3.txt @@ -0,0 +1,40 @@ +asgiref==3.8.1 +aws-xray-sdk==2.12.1 +boto3==1.35.16 +botocore==1.35.16 +aiobotocore==2.15.0 +certifi==2024.7.4 +cffi==1.17.0 +charset-normalizer==3.3.2 +cryptography==43.0.1 +Deprecated==1.2.14 +docker==7.0.0 +idna==3.7 +iniconfig==2.0.0 +Jinja2==3.1.6 +jmespath==1.0.1 +MarkupSafe==2.1.5 +moto==5.1.11 +packaging==24.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pycparser==2.21 +pytest==7.4.4 +pytest-vcr==1.0.2 +python-dateutil==2.8.2 +pytz==2024.1 +PyYAML==6.0.1 +requests==2.32.3 +responses==0.25.0 +s3transfer==0.10.0 +six==1.16.0 +tomli==2.0.1 +typing_extensions==4.12.2 +urllib3==1.26.19 +Werkzeug==3.0.6 +wrapt==1.16.0 +xmltodict==0.13.0 +zipp==3.19.2 +-e opentelemetry-instrumentation +-e propagator/opentelemetry-propagator-aws-xray +-e instrumentation/opentelemetry-instrumentation-botocore diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_aiobotocore_instrumentation.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_aiobotocore_instrumentation.py new file mode 100644 index 00000000000..216f2e29bed --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_aiobotocore_instrumentation.py @@ -0,0 +1,460 @@ +# 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. + +# pylint:disable=too-many-public-methods +import asyncio +import importlib.util +import json +import unittest +from typing import Any +from unittest.mock import Mock, call, patch + +import botocore.stub +from botocore.exceptions import ClientError + +from opentelemetry import trace as trace_api +from opentelemetry.instrumentation.auto_instrumentation import ( + _load_instrumentors, +) +from opentelemetry.instrumentation.botocore import AiobotocoreInstrumentor +from opentelemetry.instrumentation.utils import suppress_instrumentation +from opentelemetry.semconv._incubating.attributes.cloud_attributes import ( + CLOUD_REGION, +) +from opentelemetry.semconv._incubating.attributes.http_attributes import ( + HTTP_STATUS_CODE, +) +from opentelemetry.semconv._incubating.attributes.rpc_attributes import ( + RPC_METHOD, + RPC_SERVICE, + RPC_SYSTEM, +) +from opentelemetry.semconv.attributes.exception_attributes import ( + EXCEPTION_MESSAGE, + EXCEPTION_STACKTRACE, + EXCEPTION_TYPE, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.test.test_base import TestBase + +_REQUEST_ID_REGEX_MATCH = r"[A-Za-z0-9]{52}" + +aiobotocore_installed = importlib.util.find_spec("aiobotocore") is not None + + +@unittest.skipIf(not aiobotocore_installed, "aiobotocore is not installed") +class TestAiobotocoreInstrumentor(TestBase): + """Aiobotocore integration testsuite""" + + def setUp(self): + # pylint: disable-next=import-outside-toplevel + import aiobotocore.session # noqa: PLC0415 + + super().setUp() + AiobotocoreInstrumentor().instrument() + self.session = aiobotocore.session.get_session() + self.session.set_credentials( + access_key="access-key", + secret_key="secret-key", + ) + self.region = "us-west-2" + + def tearDown(self): + super().tearDown() + AiobotocoreInstrumentor().uninstrument() + + def _default_span_attributes(self, service: str, operation: str): + return { + RPC_SYSTEM: "aws-api", + RPC_SERVICE: service, + RPC_METHOD: operation, + CLOUD_REGION: self.region, + "retry_attempts": 0, + HTTP_STATUS_CODE: 200, + SERVER_ADDRESS: f"{service.lower()}.{self.region}.amazonaws.com", + SERVER_PORT: 443, + } + + def assert_only_span(self): + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(1, len(spans)) + return spans[0] + + def assert_span( + self, + service: str, + operation: str, + request_id=None, + attributes=None, + ): + span = self.assert_only_span() + expected = self._default_span_attributes(service, operation) + if attributes: + expected.update(attributes) + + span_attributes_request_id = "aws.request_id" + if request_id is _REQUEST_ID_REGEX_MATCH: + actual_request_id = span.attributes[span_attributes_request_id] + self.assertRegex(actual_request_id, _REQUEST_ID_REGEX_MATCH) + expected[span_attributes_request_id] = actual_request_id + elif request_id is not None: + expected[span_attributes_request_id] = request_id + + self.assertSpanHasAttributes(span, expected) + self.assertEqual(f"{service}.{operation}", span.name) + return span + + def _make_client(self, service: str): + return self.session.create_client(service, region_name=self.region) + + @staticmethod + def _make_response_meta(request_id: str) -> dict[str, Any]: + return { + "RequestId": request_id, + "RetryAttempts": 0, + "HTTPStatusCode": 200, + } + + def test_traced_client_ec2(self): + """Test basic EC2 client tracing with stubbed response.""" + request_id = "fdcdcab1-ae5c-489e-9c33-4637c5dda355" + + async def _test(): + async with self._make_client("ec2") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_response( + "describe_instances", + { + "Reservations": [], + "ResponseMetadata": self._make_response_meta( + request_id + ), + }, + ) + await client.describe_instances() + + asyncio.run(_test()) + self.assert_span("EC2", "DescribeInstances", request_id=request_id) + + def test_traced_client_s3(self): + """Test S3 client tracing with stubbed response.""" + request_id = "s3-request-id-12345" + + async def _test(): + async with self._make_client("s3") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_response( + "list_buckets", + { + "Buckets": [], + "Owner": {"ID": "owner-id"}, + "ResponseMetadata": self._make_response_meta( + request_id + ), + }, + ) + await client.list_buckets() + + asyncio.run(_test()) + self.assert_span("S3", "ListBuckets", request_id=request_id) + + def test_no_op_tracer_provider(self): + """Test that no spans are created when using NoOpTracerProvider.""" + AiobotocoreInstrumentor().uninstrument() + AiobotocoreInstrumentor().instrument( + tracer_provider=trace_api.NoOpTracerProvider() + ) + + async def _test(): + async with self._make_client("ec2") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_response( + "describe_instances", + { + "Reservations": [], + "ResponseMetadata": self._make_response_meta( + "test-id" + ), + }, + ) + await client.describe_instances() + + asyncio.run(_test()) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 0) + + def test_not_recording(self): + """Test behavior when span is not recording.""" + mock_tracer = Mock() + mock_span = Mock() + mock_span.is_recording.return_value = False + mock_tracer.start_span.return_value = mock_span + + async def _test(): + with patch("opentelemetry.trace.get_tracer") as tracer: + tracer.return_value = mock_tracer + async with self._make_client("ec2") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_response( + "describe_instances", + { + "Reservations": [], + "ResponseMetadata": self._make_response_meta( + "test-id" + ), + }, + ) + await client.describe_instances() + self.assertFalse(mock_span.is_recording()) + self.assertTrue(mock_span.is_recording.called) + self.assertFalse(mock_span.set_attribute.called) + self.assertFalse(mock_span.set_status.called) + + asyncio.run(_test()) + + def test_client_error(self): + """Test that ClientError is properly traced with error status.""" + + async def _test(): + async with self._make_client("s3") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_client_error( + "get_object", + service_error_code="NoSuchKey", + service_message="The specified key does not exist.", + http_status_code=404, + ) + with self.assertRaises(ClientError): + await client.get_object( + Bucket="test-bucket", Key="test-key" + ) + + asyncio.run(_test()) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(1, len(spans)) + span = spans[0] + + self.assertIs(span.status.status_code, trace_api.StatusCode.ERROR) + self.assertEqual("S3.GetObject", span.name) + + # Verify exception event was recorded + self.assertEqual(1, len(span.events)) + event = span.events[0] + self.assertIn(EXCEPTION_STACKTRACE, event.attributes) + self.assertIn(EXCEPTION_TYPE, event.attributes) + self.assertIn(EXCEPTION_MESSAGE, event.attributes) + + def test_suppress_instrumentation(self): + """Test that instrumentation can be suppressed.""" + + async def _test(): + async with self._make_client("ec2") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_response( + "describe_instances", + { + "Reservations": [], + "ResponseMetadata": self._make_response_meta( + "test-id" + ), + }, + ) + stubber.add_response( + "describe_instances", + { + "Reservations": [], + "ResponseMetadata": self._make_response_meta( + "test-id-2" + ), + }, + ) + with suppress_instrumentation(): + await client.describe_instances() + await client.describe_instances() + + asyncio.run(_test()) + self.assertEqual(0, len(self.get_finished_spans())) + + def test_request_hook(self): + """Test that request hook is called with correct parameters.""" + request_hook_service_attribute_name = "request_hook.service_name" + request_hook_operation_attribute_name = "request_hook.operation_name" + request_hook_api_params_attribute_name = "request_hook.api_params" + + def request_hook(span, service_name, operation_name, api_params): + hook_attributes = { + request_hook_service_attribute_name: service_name, + request_hook_operation_attribute_name: operation_name, + request_hook_api_params_attribute_name: json.dumps(api_params), + } + span.set_attributes(hook_attributes) + + AiobotocoreInstrumentor().uninstrument() + AiobotocoreInstrumentor().instrument(request_hook=request_hook) + + request_id = "hook-test-request-id" + + async def _test(): + async with self._make_client("s3") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_response( + "list_objects_v2", + { + "Contents": [], + "ResponseMetadata": self._make_response_meta( + request_id + ), + }, + expected_params={"Bucket": "test-bucket"}, + ) + await client.list_objects_v2(Bucket="test-bucket") + + asyncio.run(_test()) + + self.assert_span( + "S3", + "ListObjectsV2", + request_id=request_id, + attributes={ + request_hook_service_attribute_name: "s3", + request_hook_operation_attribute_name: "ListObjectsV2", + request_hook_api_params_attribute_name: json.dumps( + {"Bucket": "test-bucket"} + ), + }, + ) + + def test_response_hook(self): + """Test that response hook is called with correct parameters.""" + response_hook_service_attribute_name = "response_hook.service_name" + response_hook_operation_attribute_name = "response_hook.operation_name" + response_hook_bucket_count_attribute_name = ( + "response_hook.bucket_count" + ) + + def response_hook(span, service_name, operation_name, result): + hook_attributes = { + response_hook_service_attribute_name: service_name, + response_hook_operation_attribute_name: operation_name, + response_hook_bucket_count_attribute_name: len( + result["Buckets"] + ), + } + span.set_attributes(hook_attributes) + + AiobotocoreInstrumentor().uninstrument() + AiobotocoreInstrumentor().instrument(response_hook=response_hook) + + request_id = "response-hook-test-id" + + async def _test(): + async with self._make_client("s3") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_response( + "list_buckets", + { + "Buckets": [ + {"Name": "bucket1"}, + {"Name": "bucket2"}, + ], + "Owner": {"ID": "owner-id"}, + "ResponseMetadata": self._make_response_meta( + request_id + ), + }, + ) + await client.list_buckets() + + asyncio.run(_test()) + + self.assert_span( + "S3", + "ListBuckets", + request_id=request_id, + attributes={ + response_hook_service_attribute_name: "s3", + response_hook_operation_attribute_name: "ListBuckets", + response_hook_bucket_count_attribute_name: 2, + }, + ) + + def test_multiple_operations(self): + """Test tracing multiple sequential operations.""" + + async def _test(): + async with self._make_client("s3") as client: + with botocore.stub.Stubber(client) as stubber: + stubber.add_response( + "list_buckets", + { + "Buckets": [], + "Owner": {"ID": "owner-id"}, + "ResponseMetadata": self._make_response_meta( + "req-1" + ), + }, + ) + stubber.add_response( + "list_buckets", + { + "Buckets": [], + "Owner": {"ID": "owner-id"}, + "ResponseMetadata": self._make_response_meta( + "req-2" + ), + }, + ) + await client.list_buckets() + await client.list_buckets() + + asyncio.run(_test()) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(2, len(spans)) + + for span in spans: + self.assertEqual("S3.ListBuckets", span.name) + + self.assertEqual("req-1", spans[0].attributes["aws.request_id"]) + self.assertEqual("req-2", spans[1].attributes["aws.request_id"]) + + @patch( + "opentelemetry.instrumentation.auto_instrumentation._load.get_dist_dependency_conflicts" + ) + @patch("opentelemetry.instrumentation.auto_instrumentation._load._logger") + def test_instruments_with_aiobotocore_installed( + self, mock_logger, mock_dep + ): + mock_distro = Mock() + mock_dep.return_value = None + mock_distro.load_instrumentor.return_value = None + _load_instrumentors(mock_distro) + self.assertEqual(len(mock_distro.load_instrumentor.call_args_list), 2) + eps = [ + c[0][0].name for c in mock_distro.load_instrumentor.call_args_list + ] + assert "aiobotocore" in eps + assert "botocore" in eps + + mock_logger.debug.assert_has_calls( + [ + call("Instrumented %s", "aiobotocore"), + call("Instrumented %s", "botocore"), + ], + any_order=True, + ) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py index 4cc259a860f..e5efa882ee1 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py @@ -13,13 +13,17 @@ # limitations under the License. import json import os -from unittest.mock import ANY, Mock, patch +from importlib.metadata import EntryPoint +from unittest.mock import ANY, Mock, call, patch import botocore.session from botocore.exceptions import ParamValidationError from moto import mock_aws # pylint: disable=import-error from opentelemetry import trace as trace_api +from opentelemetry.instrumentation.auto_instrumentation import ( + _load_instrumentors, +) from opentelemetry.instrumentation.botocore import BotocoreInstrumentor from opentelemetry.instrumentation.utils import ( suppress_http_instrumentation, @@ -568,3 +572,33 @@ def test_server_attributes_with_custom_endpoint(self): SERVER_PORT: 2025, }, ) + + @patch( + "opentelemetry.instrumentation.auto_instrumentation._load.get_dist_dependency_conflicts" + ) + @patch("opentelemetry.instrumentation.auto_instrumentation._load._logger") + def test_instruments_with_botocore_installed(self, mock_logger, mock_dep): + def _load_instrumentor(ep: EntryPoint, **kwargs): + # simulate aiobotocore not being present + if ep.name == "aiobotocore": + raise ModuleNotFoundError("aiobotocore") + + mock_distro = Mock() + mock_dep.return_value = None + mock_distro.load_instrumentor.side_effect = _load_instrumentor + _load_instrumentors(mock_distro) + eps = [ + c[0][0].name for c in mock_distro.load_instrumentor.call_args_list + ] + self.assertIn("botocore", eps) + mock_logger.debug.assert_has_calls( + [ + call("Instrumented %s", "botocore"), + call( + "Skipping instrumentation %s: %s", + "aiobotocore", + "aiobotocore", + ), + ], + any_order=True, + ) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 2a0d42507a4..0eb4c38733e 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -64,6 +64,10 @@ "library": "botocore ~= 1.0", "instrumentation": "opentelemetry-instrumentation-botocore==0.62b0.dev", }, + { + "library": "aiobotocore ~= 2.0", + "instrumentation": "opentelemetry-instrumentation-botocore==0.62b0.dev", + }, { "library": "cassandra-driver ~= 3.25", "instrumentation": "opentelemetry-instrumentation-cassandra==0.62b0.dev", diff --git a/pyproject.toml b/pyproject.toml index 5980aea2eab..c877d5f0380 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ dependencies = [ "opentelemetry-instrumentation-asyncpg[instruments]", "opentelemetry-instrumentation-aws-lambda[instruments]", "opentelemetry-instrumentation-boto3sqs[instruments]", - "opentelemetry-instrumentation-botocore[instruments]", + "opentelemetry-instrumentation-botocore[instruments-any]", "opentelemetry-instrumentation-cassandra[instruments]", "opentelemetry-instrumentation-celery[instruments]", "opentelemetry-instrumentation-click[instruments]", diff --git a/tox.ini b/tox.ini index fdfd33afd58..b351bf13eee 100644 --- a/tox.ini +++ b/tox.ini @@ -89,6 +89,7 @@ envlist = ; opentelemetry-instrumentation-botocore py3{9,10,11,12,13,14}-test-instrumentation-botocore-{0,1}-{wrapt1,wrapt2} + py3{9,10,11,12,13,14}-test-instrumentation-botocore-{2,3} ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 ; pypy3-test-instrumentation-botocore lint-instrumentation-botocore @@ -597,7 +598,10 @@ deps = botocore-0-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-0-wrapt2.txt botocore-1-wrapt1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt1.txt botocore-1-wrapt2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt2.txt - lint-instrumentation-botocore: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-1-wrapt2.txt + ; Note: aiobotocore is not compatible with wrapt2 + botocore-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-2.txt + botocore-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-3.txt + lint-instrumentation-botocore: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-botocore/test-requirements-3.txt cassandra: {[testenv]test_deps} cassandra-driver: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-cassandra/test-requirements.txt diff --git a/uv.lock b/uv.lock index 1ffeaf9c667..14d5ea35b6f 100644 --- a/uv.lock +++ b/uv.lock @@ -95,6 +95,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7c/91/513971861d845d28160ecb205ae2cfaf618b16918a9cd4e0b832b5360ce7/aio_pika-9.5.8-py3-none-any.whl", hash = "sha256:f4c6cb8a6c5176d00f39fd7431e9702e638449bc6e86d1769ad7548b2a506a8d", size = 54397, upload-time = "2025-11-12T10:37:08.374Z" }, ] +[[package]] +name = "aiobotocore" +version = "2.26.0" +source = { registry = "https://pypi.org/simple/" } +dependencies = [ + { name = "aiohttp" }, + { name = "aioitertools" }, + { name = "botocore" }, + { name = "jmespath" }, + { name = "multidict" }, + { name = "python-dateutil" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/f8/99fa90d9c25b78292899fd4946fce97b6353838b5ecc139ad8ba1436e70c/aiobotocore-2.26.0.tar.gz", hash = "sha256:50567feaf8dfe2b653570b4491f5bc8c6e7fb9622479d66442462c021db4fadc", size = 122026, upload-time = "2025-11-28T07:54:59.956Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/58/3bf0b7d474607dc7fd67dd1365c4e0f392c8177eaf4054e5ddee3ebd53b5/aiobotocore-2.26.0-py3-none-any.whl", hash = "sha256:a793db51c07930513b74ea7a95bd79aaa42f545bdb0f011779646eafa216abec", size = 87333, upload-time = "2025-11-28T07:54:58.457Z" }, +] + [[package]] name = "aiohappyeyeballs" version = "2.6.1" @@ -224,6 +242,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/63/278a98c715ae467624eafe375542d8ba9b4383a016df8fdefe0ae28382a7/aiohttp-3.13.3-cp314-cp314t-win_amd64.whl", hash = "sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344", size = 499694, upload-time = "2026-01-03T17:32:24.546Z" }, ] +[[package]] +name = "aioitertools" +version = "0.13.0" +source = { registry = "https://pypi.org/simple/" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/3c/53c4a17a05fb9ea2313ee1777ff53f5e001aefd5cc85aa2f4c2d982e1e38/aioitertools-0.13.0.tar.gz", hash = "sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c", size = 19322, upload-time = "2025-11-06T22:17:07.609Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl", hash = "sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be", size = 24182, upload-time = "2025-11-06T22:17:06.502Z" }, +] + [[package]] name = "aiokafka" version = "0.13.0" @@ -532,30 +559,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.42.53" +version = "1.41.5" source = { registry = "https://pypi.org/simple/" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/ef/03460914019db52301a6084460f0dd738f3f9e89d2ddf5bd33cef8168e63/boto3-1.42.53.tar.gz", hash = "sha256:56bc79388763995852b6d3fe48023e661e63fc2e60a921273c422d0171b9fbfb", size = 112812, upload-time = "2026-02-19T20:33:58.422Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/81/450cd4143864959264a3d80f9246175a20de8c1e50ec889c710eaa28cdd9/boto3-1.41.5.tar.gz", hash = "sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17", size = 111594, upload-time = "2025-11-26T20:27:47.021Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/ea/08dfba25a5822a7254b20aa905a9937177ca1532dd7f47c926875dd87299/boto3-1.42.53-py3-none-any.whl", hash = "sha256:3bd32f3508a6e9851671d0ef3b1f9e8ee7e8c095aa0488bcd9e86074aef5b7eb", size = 140555, upload-time = "2026-02-19T20:33:55.691Z" }, + { url = "https://files.pythonhosted.org/packages/3c/56/f47a80254ed4991cce9a2f6d8ae8aafbc8df1c3270e966b2927289e5a12f/boto3-1.41.5-py3-none-any.whl", hash = "sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745", size = 139344, upload-time = "2025-11-26T20:27:45.571Z" }, ] [[package]] name = "botocore" -version = "1.42.53" +version = "1.41.5" source = { registry = "https://pypi.org/simple/" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7a/b6/0b2ab38e422e93f28b7a394a29881a9d767b79831fa1957a3ccab996a70e/botocore-1.42.53.tar.gz", hash = "sha256:0bc1a2e1b6ae4c8397c9bede3bb9007b4f16e159ef2ca7f24837e31d5860caac", size = 14918644, upload-time = "2026-02-19T20:33:44.814Z" } +sdist = { url = "https://files.pythonhosted.org/packages/90/22/7fe08c726a2e3b11a0aef8bf177e83891c9cb2dc1809d35c9ed91a9e60e6/botocore-1.41.5.tar.gz", hash = "sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf", size = 14668152, upload-time = "2025-11-26T20:27:38.026Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/dc/cf3b2ec4a419b20d2cd6ba8e1961bc59b7ec9801339628e31551dac23801/botocore-1.42.53-py3-none-any.whl", hash = "sha256:1255db56bc0a284a8caa182c20966277e6c8871b6881cf816d40e993fa5da503", size = 14589472, upload-time = "2026-02-19T20:33:40.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/4e/21cd0b8f365449f1576f93de1ec8718ed18a7a3bc086dfbdeb79437bba7a/botocore-1.41.5-py3-none-any.whl", hash = "sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a", size = 14337008, upload-time = "2025-11-26T20:27:35.208Z" }, ] [[package]] @@ -3072,20 +3099,22 @@ dependencies = [ ] [package.optional-dependencies] -instruments = [ +instruments-any = [ + { name = "aiobotocore" }, { name = "botocore" }, ] [package.metadata] requires-dist = [ - { name = "botocore", marker = "extra == 'instruments'", specifier = "~=1.0" }, + { name = "aiobotocore", marker = "extra == 'instruments-any'", specifier = "~=2.0" }, + { name = "botocore", marker = "extra == 'instruments-any'", specifier = "~=1.0" }, { name = "opentelemetry-api", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-api&branch=main" }, { name = "opentelemetry-instrumentation", editable = "opentelemetry-instrumentation" }, { name = "opentelemetry-propagator-aws-xray", editable = "propagator/opentelemetry-propagator-aws-xray" }, { name = "opentelemetry-semantic-conventions", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=opentelemetry-semantic-conventions&branch=main" }, { name = "wrapt", specifier = ">=1.0.0,<3.0.0" }, ] -provides-extras = ["instruments"] +provides-extras = ["instruments", "instruments-any"] [[package]] name = "opentelemetry-instrumentation-cassandra" @@ -4222,7 +4251,7 @@ dependencies = [ { name = "opentelemetry-instrumentation-asyncpg", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-aws-lambda" }, { name = "opentelemetry-instrumentation-boto3sqs", extra = ["instruments"] }, - { name = "opentelemetry-instrumentation-botocore", extra = ["instruments"] }, + { name = "opentelemetry-instrumentation-botocore", extra = ["instruments-any"] }, { name = "opentelemetry-instrumentation-cassandra" }, { name = "opentelemetry-instrumentation-celery", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-click", extra = ["instruments"] }, @@ -4294,7 +4323,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation-asyncpg", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-asyncpg" }, { name = "opentelemetry-instrumentation-aws-lambda", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-aws-lambda" }, { name = "opentelemetry-instrumentation-boto3sqs", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-boto3sqs" }, - { name = "opentelemetry-instrumentation-botocore", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-botocore" }, + { name = "opentelemetry-instrumentation-botocore", extras = ["instruments-any"], editable = "instrumentation/opentelemetry-instrumentation-botocore" }, { name = "opentelemetry-instrumentation-cassandra", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-cassandra" }, { name = "opentelemetry-instrumentation-celery", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-celery" }, { name = "opentelemetry-instrumentation-click", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-click" }, @@ -5689,14 +5718,14 @@ wheels = [ [[package]] name = "s3transfer" -version = "0.16.0" +version = "0.15.0" source = { registry = "https://pypi.org/simple/" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/04/74127fc843314818edfa81b5540e26dd537353b123a4edc563109d8f17dd/s3transfer-0.16.0.tar.gz", hash = "sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920", size = 153827, upload-time = "2025-12-01T02:30:59.114Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bb/940d6af975948c1cc18f44545ffb219d3c35d78ec972b42ae229e8e37e08/s3transfer-0.15.0.tar.gz", hash = "sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379", size = 152185, upload-time = "2025-11-20T20:28:56.327Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl", hash = "sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe", size = 86830, upload-time = "2025-12-01T02:30:57.729Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e1/5ef25f52973aa12a19cf4e1375d00932d7fb354ffd310487ba7d44225c1a/s3transfer-0.15.0-py3-none-any.whl", hash = "sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852", size = 85984, upload-time = "2025-11-20T20:28:55.046Z" }, ] [[package]] From 10339b6c12304c810f56cf20afc4fe5a9963dd90 Mon Sep 17 00:00:00 2001 From: Riya Chaturvedi Date: Thu, 19 Mar 2026 15:44:21 +0530 Subject: [PATCH 29/78] refactor(docker-tests): replace SpanAttributes with semconv attributes (#4339) * refactor(docker-tests): replace SpanAttributes with semconv attributes Refs #3475 * update changelog for PR #4339 * Update CHANGELOG.md --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 + .../tests/asyncpg/test_asyncpg_functional.py | 110 ++++++++++-------- .../tests/celery/test_celery_functional.py | 48 ++++---- .../tests/mysql/test_mysql_functional.py | 20 +++- .../tests/postgres/test_aiopg_functional.py | 30 +++-- .../tests/postgres/test_psycopg_functional.py | 25 ++-- .../tests/pymongo/test_pymongo_functional.py | 20 +++- .../tests/pymysql/test_pymysql_functional.py | 20 +++- .../tests/redis/test_redis_functional.py | 67 ++++++----- .../tests/sqlalchemy_tests/mixins.py | 18 +-- .../tests/sqlalchemy_tests/test_mssql.py | 24 ++-- .../tests/sqlalchemy_tests/test_mysql.py | 22 ++-- .../tests/sqlalchemy_tests/test_postgres.py | 17 ++- .../tests/sqlalchemy_tests/test_sqlite.py | 9 +- 14 files changed, 264 insertions(+), 168 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d3dcff52a7..564340ae262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `opentelemetry-docker-tests`: Replace deprecated `SpanAttributes` from `opentelemetry.semconv.trace` with `opentelemetry.semconv._incubating.attributes` + ([#4339](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4339)) - Fix intermittent `Core Contrib Test` CI failures caused by GitHub git CDN SHA propagation lag by installing core packages from the already-checked-out local copy instead of a second git clone ([#4305](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4305)) - Don't import module in unwrap if not already imported diff --git a/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py b/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py index e14ba072712..8242353ae7a 100644 --- a/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py +++ b/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py @@ -12,7 +12,17 @@ from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( InMemorySpanExporter, ) -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_STATEMENT, + DB_SYSTEM, + DB_USER, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, + NET_TRANSPORT, +) from opentelemetry.test.test_base import TestBase from opentelemetry.trace import StatusCode @@ -31,19 +41,19 @@ def async_call(coro): class CheckSpanMixin: def check_span(self, span, expected_db_name=POSTGRES_DB_NAME): self.assertEqual( - span.attributes[SpanAttributes.DB_SYSTEM], "postgresql" + span.attributes[DB_SYSTEM], "postgresql" ) self.assertEqual( - span.attributes[SpanAttributes.DB_NAME], expected_db_name + span.attributes[DB_NAME], expected_db_name ) self.assertEqual( - span.attributes[SpanAttributes.DB_USER], POSTGRES_USER + span.attributes[DB_USER], POSTGRES_USER ) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_NAME], POSTGRES_HOST + span.attributes[NET_PEER_NAME], POSTGRES_HOST ) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_PORT], POSTGRES_PORT + span.attributes[NET_PEER_PORT], POSTGRES_PORT ) @@ -75,7 +85,7 @@ def test_instrumented_execute_method_without_arguments(self, *_, **__): self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;" + spans[0].attributes[DB_STATEMENT], "SELECT 42;" ) def test_instrumented_execute_method_error(self, *_, **__): @@ -87,7 +97,7 @@ def test_instrumented_execute_method_error(self, *_, **__): self.assertIs(StatusCode.ERROR, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, POSTGRES_DB_NAME) - self.assertEqual(spans[0].attributes[SpanAttributes.DB_STATEMENT], "") + self.assertEqual(spans[0].attributes[DB_STATEMENT], "") def test_instrumented_fetch_method_without_arguments(self, *_, **__): """Should create a span from fetch().""" @@ -98,7 +108,7 @@ def test_instrumented_fetch_method_without_arguments(self, *_, **__): self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;" + spans[0].attributes[DB_STATEMENT], "SELECT 42;" ) def test_instrumented_fetch_method_empty_query(self, *_, **__): @@ -109,7 +119,7 @@ def test_instrumented_fetch_method_empty_query(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, POSTGRES_DB_NAME) - self.assertEqual(spans[0].attributes[SpanAttributes.DB_STATEMENT], "") + self.assertEqual(spans[0].attributes[DB_STATEMENT], "") def test_instrumented_fetchval_method_without_arguments(self, *_, **__): """Should create a span for fetchval().""" @@ -120,7 +130,7 @@ def test_instrumented_fetchval_method_without_arguments(self, *_, **__): self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;" + spans[0].attributes[DB_STATEMENT], "SELECT 42;" ) def test_instrumented_fetchval_method_empty_query(self, *_, **__): @@ -131,7 +141,7 @@ def test_instrumented_fetchval_method_empty_query(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, POSTGRES_DB_NAME) - self.assertEqual(spans[0].attributes[SpanAttributes.DB_STATEMENT], "") + self.assertEqual(spans[0].attributes[DB_STATEMENT], "") def test_instrumented_fetchrow_method_without_arguments(self, *_, **__): """Should create a span for fetchrow().""" @@ -142,7 +152,7 @@ def test_instrumented_fetchrow_method_without_arguments(self, *_, **__): self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;" + spans[0].attributes[DB_STATEMENT], "SELECT 42;" ) def test_instrumented_fetchrow_method_empty_query(self, *_, **__): @@ -153,7 +163,7 @@ def test_instrumented_fetchrow_method_empty_query(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, POSTGRES_DB_NAME) - self.assertEqual(spans[0].attributes[SpanAttributes.DB_STATEMENT], "") + self.assertEqual(spans[0].attributes[DB_STATEMENT], "") def test_instrumented_cursor_execute_method_without_arguments( self, *_, **__ @@ -173,7 +183,7 @@ async def _cursor_execute(): self.check_span(spans[0]) self.assertEqual(spans[0].name, "BEGIN;") self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "BEGIN;" + spans[0].attributes[DB_STATEMENT], "BEGIN;" ) self.assertIs(StatusCode.UNSET, spans[0].status.status_code) @@ -181,7 +191,7 @@ async def _cursor_execute(): self.check_span(span) self.assertEqual(span.name, "CURSOR: SELECT") self.assertEqual( - span.attributes[SpanAttributes.DB_STATEMENT], + span.attributes[DB_STATEMENT], "SELECT generate_series(0, 5);", ) self.assertIs(StatusCode.UNSET, span.status.status_code) @@ -189,7 +199,7 @@ async def _cursor_execute(): self.check_span(spans[-1]) self.assertEqual(spans[-1].name, "COMMIT;") self.assertEqual( - spans[-1].attributes[SpanAttributes.DB_STATEMENT], "COMMIT;" + spans[-1].attributes[DB_STATEMENT], "COMMIT;" ) def test_instrumented_cursor_execute_method_empty_query(self, *_, **__): @@ -206,18 +216,18 @@ async def _cursor_execute(): self.check_span(spans[0]) self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "BEGIN;" + spans[0].attributes[DB_STATEMENT], "BEGIN;" ) self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[1]) self.assertEqual(spans[1].name, f"CURSOR: {POSTGRES_DB_NAME}") - self.assertEqual(spans[1].attributes[SpanAttributes.DB_STATEMENT], "") + self.assertEqual(spans[1].attributes[DB_STATEMENT], "") self.assertIs(StatusCode.UNSET, spans[1].status.status_code) self.check_span(spans[2]) self.assertEqual( - spans[2].attributes[SpanAttributes.DB_STATEMENT], "COMMIT;" + spans[2].attributes[DB_STATEMENT], "COMMIT;" ) def test_instrumented_remove_comments(self, *_, **__): @@ -235,21 +245,21 @@ def test_instrumented_remove_comments(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.assertEqual(spans[0].name, "SELECT") self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], + spans[0].attributes[DB_STATEMENT], "/* leading comment */ SELECT 42;", ) self.check_span(spans[1]) self.assertIs(StatusCode.UNSET, spans[1].status.status_code) self.assertEqual(spans[1].name, "SELECT") self.assertEqual( - spans[1].attributes[SpanAttributes.DB_STATEMENT], + spans[1].attributes[DB_STATEMENT], "/* leading comment */ SELECT 42; /* trailing comment */", ) self.check_span(spans[2]) self.assertIs(StatusCode.UNSET, spans[2].status.status_code) self.assertEqual(spans[2].name, "SELECT") self.assertEqual( - spans[2].attributes[SpanAttributes.DB_STATEMENT], + spans[2].attributes[DB_STATEMENT], "SELECT 42; /* trailing comment */", ) @@ -266,19 +276,19 @@ async def _transaction_execute(): self.assertEqual(3, len(spans)) self.check_span(spans[0]) self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "BEGIN;" + spans[0].attributes[DB_STATEMENT], "BEGIN;" ) self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[1]) self.assertEqual( - spans[1].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;" + spans[1].attributes[DB_STATEMENT], "SELECT 42;" ) self.assertIs(StatusCode.UNSET, spans[1].status.status_code) self.check_span(spans[2]) self.assertEqual( - spans[2].attributes[SpanAttributes.DB_STATEMENT], "COMMIT;" + spans[2].attributes[DB_STATEMENT], "COMMIT;" ) self.assertIs(StatusCode.UNSET, spans[2].status.status_code) @@ -297,20 +307,20 @@ async def _transaction_execute(): self.check_span(spans[0]) self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "BEGIN;" + spans[0].attributes[DB_STATEMENT], "BEGIN;" ) self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[1]) self.assertEqual( - spans[1].attributes[SpanAttributes.DB_STATEMENT], + spans[1].attributes[DB_STATEMENT], "SELECT 42::uuid;", ) self.assertEqual(StatusCode.ERROR, spans[1].status.status_code) self.check_span(spans[2]) self.assertEqual( - spans[2].attributes[SpanAttributes.DB_STATEMENT], "ROLLBACK;" + spans[2].attributes[DB_STATEMENT], "ROLLBACK;" ) self.assertIs(StatusCode.UNSET, spans[2].status.status_code) @@ -322,7 +332,7 @@ def test_instrumented_method_doesnt_capture_parameters(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;" + spans[0].attributes[DB_STATEMENT], "SELECT $1;" ) @@ -357,7 +367,7 @@ def test_instrumented_execute_method_with_arguments(self, *_, **__): self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;" + spans[0].attributes[DB_STATEMENT], "SELECT $1;" ) self.assertEqual( spans[0].attributes["db.statement.parameters"], "('1',)" @@ -372,7 +382,7 @@ def test_instrumented_fetch_method_with_arguments(self, *_, **__): self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;" + spans[0].attributes[DB_STATEMENT], "SELECT $1;" ) self.assertEqual( spans[0].attributes["db.statement.parameters"], "('1',)" @@ -386,7 +396,7 @@ def test_instrumented_executemany_method_with_arguments(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;" + spans[0].attributes[DB_STATEMENT], "SELECT $1;" ) self.assertEqual( spans[0].attributes["db.statement.parameters"], "([['1'], ['2']],)" @@ -401,7 +411,7 @@ def test_instrumented_execute_interface_error_method(self, *_, **__): self.assertIs(StatusCode.ERROR, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual( - spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;" + spans[0].attributes[DB_STATEMENT], "SELECT 42;" ) self.assertEqual( spans[0].attributes["db.statement.parameters"], "(1, 2, 3)" @@ -415,7 +425,7 @@ def test_instrumented_executemany_method_empty_query(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, POSTGRES_DB_NAME) - self.assertEqual(spans[0].attributes[SpanAttributes.DB_STATEMENT], "") + self.assertEqual(spans[0].attributes[DB_STATEMENT], "") self.assertEqual( spans[0].attributes["db.statement.parameters"], "([],)" ) @@ -430,7 +440,7 @@ def test_instrumented_fetch_method_broken_asyncpg(self, *_, **__): self.assertEqual(len(spans), 1) self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.assertEqual(spans[0].name, "postgresql") - self.assertEqual(spans[0].attributes[SpanAttributes.DB_STATEMENT], "") + self.assertEqual(spans[0].attributes[DB_STATEMENT], "") class _FakeParams: @@ -482,13 +492,13 @@ async def _fake_execute(*args, **kwargs): self.assertEqual( span.attributes, { - SpanAttributes.DB_SYSTEM: "postgresql", - SpanAttributes.DB_NAME: "testdb", - SpanAttributes.DB_USER: "dbuser", - SpanAttributes.NET_PEER_NAME: "db.example.com", - SpanAttributes.NET_PEER_PORT: 5432, - SpanAttributes.NET_TRANSPORT: "ip_tcp", - SpanAttributes.DB_STATEMENT: "SELECT $1", + DB_SYSTEM: "postgresql", + DB_NAME: "testdb", + DB_USER: "dbuser", + NET_PEER_NAME: "db.example.com", + NET_PEER_PORT: 5432, + NET_TRANSPORT: "ip_tcp", + DB_STATEMENT: "SELECT $1", "db.statement.parameters": "('42',)", }, ) @@ -516,13 +526,13 @@ async def _fake_cursor_execute(*args, **kwargs): self.assertEqual( span.attributes, { - SpanAttributes.DB_SYSTEM: "postgresql", - SpanAttributes.DB_NAME: "testdb", - SpanAttributes.DB_USER: "dbuser", - SpanAttributes.NET_PEER_NAME: "db.example.com", - SpanAttributes.NET_PEER_PORT: 5432, - SpanAttributes.NET_TRANSPORT: "ip_tcp", - SpanAttributes.DB_STATEMENT: "SELECT $1", + DB_SYSTEM: "postgresql", + DB_NAME: "testdb", + DB_USER: "dbuser", + NET_PEER_NAME: "db.example.com", + NET_PEER_PORT: 5432, + NET_TRANSPORT: "ip_tcp", + DB_STATEMENT: "SELECT $1", "db.statement.parameters": "('99',)", }, ) diff --git a/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py b/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py index 0b9cb3dac5d..cf030e1e048 100644 --- a/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py +++ b/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py @@ -22,7 +22,13 @@ from opentelemetry.instrumentation.celery import CeleryInstrumentor from opentelemetry.sdk import resources from opentelemetry.sdk.trace import TracerProvider, export -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.exception_attributes import ( + EXCEPTION_MESSAGE, + EXCEPTION_TYPE, +) +from opentelemetry.semconv._incubating.attributes.messaging_attributes import ( + MESSAGING_MESSAGE_ID, +) from opentelemetry.trace import StatusCode # set a high timeout for async executions due to issues in CI @@ -106,7 +112,7 @@ def fn_task(): assert span.status.is_ok is True assert span.name == "run/test_celery_functional.fn_task" assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) == t.task_id + span.attributes.get(MESSAGING_MESSAGE_ID) == t.task_id ) assert ( span.attributes.get("celery.task_name") @@ -133,7 +139,7 @@ def fn_task(self): assert span.status.is_ok is True assert span.name == "run/test_celery_functional.fn_task" assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) == t.task_id + span.attributes.get(MESSAGING_MESSAGE_ID) == t.task_id ) assert ( span.attributes.get("celery.task_name") @@ -168,7 +174,7 @@ def fn_task_parameters(user, force_logout=False): ) assert async_span.attributes.get("celery.action") == "apply_async" assert ( - async_span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + async_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) assert ( @@ -181,7 +187,7 @@ def fn_task_parameters(user, force_logout=False): assert run_span.attributes.get("celery.action") == "run" assert run_span.attributes.get("celery.state") == "SUCCESS" assert ( - run_span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + run_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) assert ( @@ -229,7 +235,7 @@ def fn_task_parameters(user, force_logout=False): ) assert async_span.attributes.get("celery.action") == "apply_async" assert ( - async_span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + async_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) assert ( @@ -242,7 +248,7 @@ def fn_task_parameters(user, force_logout=False): assert run_span.attributes.get("celery.action") == "run" assert run_span.attributes.get("celery.state") == "SUCCESS" assert ( - run_span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + run_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) assert ( @@ -279,10 +285,10 @@ def fn_exception(): assert len(span.events) == 1 event = span.events[0] assert event.name == "exception" - assert event.attributes[SpanAttributes.EXCEPTION_TYPE] == "Exception" - assert SpanAttributes.EXCEPTION_MESSAGE in event.attributes + assert event.attributes[EXCEPTION_TYPE] == "Exception" + assert EXCEPTION_MESSAGE in event.attributes assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) assert "Task class is failing" in span.status.description @@ -313,7 +319,7 @@ def fn_exception(): == "test_celery_functional.fn_exception" ) assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) @@ -343,7 +349,7 @@ def fn_exception(): == "test_celery_functional.fn_exception" ) assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) @@ -378,7 +384,7 @@ def run(self): assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "SUCCESS" assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) @@ -414,7 +420,7 @@ def run(self): assert span.attributes.get("celery.state") == "FAILURE" assert span.status.status_code == StatusCode.ERROR assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) assert "Task class is failing" in span.status.description @@ -449,7 +455,7 @@ def run(self): assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "FAILURE" assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) @@ -477,7 +483,7 @@ def add(x, y): assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "SUCCESS" assert ( - span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) @@ -527,7 +533,7 @@ class CelerySubClass(CelerySuperClass): assert run_span.attributes.get("celery.action") == "run" assert run_span.attributes.get("celery.state") == "SUCCESS" assert ( - run_span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + run_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id ) @@ -540,7 +546,7 @@ class CelerySubClass(CelerySuperClass): assert async_run_span.attributes.get("celery.action") == "run" assert async_run_span.attributes.get("celery.state") == "SUCCESS" assert ( - async_run_span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + async_run_span.attributes.get(MESSAGING_MESSAGE_ID) != result.task_id ) @@ -554,12 +560,12 @@ class CelerySubClass(CelerySuperClass): ) assert async_span.attributes.get("celery.action") == "apply_async" assert ( - async_span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + async_span.attributes.get(MESSAGING_MESSAGE_ID) != result.task_id ) assert async_span.attributes.get( - SpanAttributes.MESSAGING_MESSAGE_ID - ) == async_run_span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID) + MESSAGING_MESSAGE_ID + ) == async_run_span.attributes.get(MESSAGING_MESSAGE_ID) def test_custom_tracer_provider(celery_app, memory_exporter): diff --git a/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py b/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py index 7f5b94fc5df..105cca0fa46 100644 --- a/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py +++ b/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py @@ -18,7 +18,15 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation.mysql import MySQLInstrumentor -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_SYSTEM, + DB_USER, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from opentelemetry.test.test_base import TestBase MYSQL_USER = os.getenv("MYSQL_USER", "testuser") @@ -65,18 +73,18 @@ def validate_spans(self, span_name): self.assertIsNotNone(db_span.parent) self.assertIs(db_span.parent, root_span.get_span_context()) self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT) - self.assertEqual(db_span.attributes[SpanAttributes.DB_SYSTEM], "mysql") + self.assertEqual(db_span.attributes[DB_SYSTEM], "mysql") self.assertEqual( - db_span.attributes[SpanAttributes.DB_NAME], MYSQL_DB_NAME + db_span.attributes[DB_NAME], MYSQL_DB_NAME ) self.assertEqual( - db_span.attributes[SpanAttributes.DB_USER], MYSQL_USER + db_span.attributes[DB_USER], MYSQL_USER ) self.assertEqual( - db_span.attributes[SpanAttributes.NET_PEER_NAME], MYSQL_HOST + db_span.attributes[NET_PEER_NAME], MYSQL_HOST ) self.assertEqual( - db_span.attributes[SpanAttributes.NET_PEER_PORT], MYSQL_PORT + db_span.attributes[NET_PEER_PORT], MYSQL_PORT ) def test_execute(self): diff --git a/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py b/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py index 93ac71a5db7..84ff4e891f4 100644 --- a/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py +++ b/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py @@ -20,7 +20,15 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation.aiopg import AiopgInstrumentor -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_SYSTEM, + DB_USER, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from opentelemetry.test.test_base import TestBase POSTGRES_HOST = os.getenv("POSTGRESQL_HOST", "127.0.0.1") @@ -75,19 +83,19 @@ def validate_spans(self, span_name): self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) self.assertEqual( - child_span.attributes[SpanAttributes.DB_SYSTEM], "postgresql" + child_span.attributes[DB_SYSTEM], "postgresql" ) self.assertEqual( - child_span.attributes[SpanAttributes.DB_NAME], POSTGRES_DB_NAME + child_span.attributes[DB_NAME], POSTGRES_DB_NAME ) self.assertEqual( - child_span.attributes[SpanAttributes.DB_USER], POSTGRES_USER + child_span.attributes[DB_USER], POSTGRES_USER ) self.assertEqual( - child_span.attributes[SpanAttributes.NET_PEER_NAME], POSTGRES_HOST + child_span.attributes[NET_PEER_NAME], POSTGRES_HOST ) self.assertEqual( - child_span.attributes[SpanAttributes.NET_PEER_PORT], POSTGRES_PORT + child_span.attributes[NET_PEER_PORT], POSTGRES_PORT ) def test_execute(self): @@ -162,19 +170,19 @@ def validate_spans(self, span_name): self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) self.assertEqual( - child_span.attributes[SpanAttributes.DB_SYSTEM], "postgresql" + child_span.attributes[DB_SYSTEM], "postgresql" ) self.assertEqual( - child_span.attributes[SpanAttributes.DB_NAME], POSTGRES_DB_NAME + child_span.attributes[DB_NAME], POSTGRES_DB_NAME ) self.assertEqual( - child_span.attributes[SpanAttributes.DB_USER], POSTGRES_USER + child_span.attributes[DB_USER], POSTGRES_USER ) self.assertEqual( - child_span.attributes[SpanAttributes.NET_PEER_NAME], POSTGRES_HOST + child_span.attributes[NET_PEER_NAME], POSTGRES_HOST ) self.assertEqual( - child_span.attributes[SpanAttributes.NET_PEER_PORT], POSTGRES_PORT + child_span.attributes[NET_PEER_PORT], POSTGRES_PORT ) def test_execute(self): diff --git a/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py b/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py index 4e2106ef8dd..ab7bcad6500 100644 --- a/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py +++ b/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py @@ -19,7 +19,16 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_STATEMENT, + DB_SYSTEM, + DB_USER, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from opentelemetry.test.test_base import TestBase POSTGRES_HOST = os.getenv("POSTGRESQL_HOST", "localhost") @@ -68,19 +77,19 @@ def validate_spans(self, span_name): self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) self.assertEqual( - child_span.attributes[SpanAttributes.DB_SYSTEM], "postgresql" + child_span.attributes[DB_SYSTEM], "postgresql" ) self.assertEqual( - child_span.attributes[SpanAttributes.DB_NAME], POSTGRES_DB_NAME + child_span.attributes[DB_NAME], POSTGRES_DB_NAME ) self.assertEqual( - child_span.attributes[SpanAttributes.DB_USER], POSTGRES_USER + child_span.attributes[DB_USER], POSTGRES_USER ) self.assertEqual( - child_span.attributes[SpanAttributes.NET_PEER_NAME], POSTGRES_HOST + child_span.attributes[NET_PEER_NAME], POSTGRES_HOST ) self.assertEqual( - child_span.attributes[SpanAttributes.NET_PEER_PORT], POSTGRES_PORT + child_span.attributes[NET_PEER_PORT], POSTGRES_PORT ) def test_execute(self): @@ -148,7 +157,7 @@ def test_composed_queries(self): span = spans[2] self.assertEqual(span.name, "SELECT") self.assertEqual( - span.attributes[SpanAttributes.DB_STATEMENT], + span.attributes[DB_STATEMENT], 'SELECT FROM "users" where "name"=\'"abc"\'', ) @@ -172,6 +181,6 @@ def test_commenter_enabled(self): span = spans[2] self.assertEqual(span.name, "SELECT") self.assertEqual( - span.attributes[SpanAttributes.DB_STATEMENT], + span.attributes[DB_STATEMENT], 'SELECT FROM "users" where "name"=\'"abc"\'', ) diff --git a/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py b/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py index c506d0452a7..bd157a01884 100644 --- a/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py +++ b/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py @@ -18,7 +18,15 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation.pymongo import PymongoInstrumentor -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_MONGODB_COLLECTION, + DB_NAME, + DB_STATEMENT, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from opentelemetry.test.test_base import TestBase MONGODB_HOST = os.getenv("MONGODB_HOST", "localhost") @@ -61,20 +69,20 @@ def validate_spans(self, expected_db_statement): self.assertIs(pymongo_span.parent, root_span.get_span_context()) self.assertIs(pymongo_span.kind, trace_api.SpanKind.CLIENT) self.assertEqual( - pymongo_span.attributes[SpanAttributes.DB_NAME], MONGODB_DB_NAME + pymongo_span.attributes[DB_NAME], MONGODB_DB_NAME ) self.assertEqual( - pymongo_span.attributes[SpanAttributes.NET_PEER_NAME], MONGODB_HOST + pymongo_span.attributes[NET_PEER_NAME], MONGODB_HOST ) self.assertEqual( - pymongo_span.attributes[SpanAttributes.NET_PEER_PORT], MONGODB_PORT + pymongo_span.attributes[NET_PEER_PORT], MONGODB_PORT ) self.assertEqual( - pymongo_span.attributes[SpanAttributes.DB_MONGODB_COLLECTION], + pymongo_span.attributes[DB_MONGODB_COLLECTION], MONGODB_COLLECTION_NAME, ) self.assertEqual( - pymongo_span.attributes[SpanAttributes.DB_STATEMENT], + pymongo_span.attributes[DB_STATEMENT], expected_db_statement, ) diff --git a/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py b/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py index 537f42377c4..dfcf4f2f184 100644 --- a/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py +++ b/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py @@ -18,7 +18,15 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_SYSTEM, + DB_USER, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from opentelemetry.test.test_base import TestBase MYSQL_USER = os.getenv("MYSQL_USER", "testuser") @@ -65,18 +73,18 @@ def validate_spans(self, span_name): self.assertIsNotNone(db_span.parent) self.assertIs(db_span.parent, root_span.get_span_context()) self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT) - self.assertEqual(db_span.attributes[SpanAttributes.DB_SYSTEM], "mysql") + self.assertEqual(db_span.attributes[DB_SYSTEM], "mysql") self.assertEqual( - db_span.attributes[SpanAttributes.DB_NAME], MYSQL_DB_NAME + db_span.attributes[DB_NAME], MYSQL_DB_NAME ) self.assertEqual( - db_span.attributes[SpanAttributes.DB_USER], MYSQL_USER + db_span.attributes[DB_USER], MYSQL_USER ) self.assertEqual( - db_span.attributes[SpanAttributes.NET_PEER_NAME], MYSQL_HOST + db_span.attributes[NET_PEER_NAME], MYSQL_HOST ) self.assertEqual( - db_span.attributes[SpanAttributes.NET_PEER_PORT], MYSQL_PORT + db_span.attributes[NET_PEER_PORT], MYSQL_PORT ) def test_execute(self): diff --git a/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py b/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py index bfb3aa1f48b..f518244ac22 100644 --- a/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py +++ b/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py @@ -27,7 +27,14 @@ from opentelemetry import trace from opentelemetry.instrumentation.redis import RedisInstrumentor -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_REDIS_DATABASE_INDEX, + DB_STATEMENT, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from opentelemetry.test.test_base import TestBase @@ -46,12 +53,12 @@ def _check_span(self, span, name): self.assertEqual(span.name, name) self.assertIs(span.status.status_code, trace.StatusCode.UNSET) self.assertEqual( - span.attributes.get(SpanAttributes.DB_REDIS_DATABASE_INDEX), 0 + span.attributes.get(DB_REDIS_DATABASE_INDEX), 0 ) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_NAME], "localhost" + span.attributes[NET_PEER_NAME], "localhost" ) - self.assertEqual(span.attributes[SpanAttributes.NET_PEER_PORT], 6379) + self.assertEqual(span.attributes[NET_PEER_PORT], 6379) def test_long_command_sanitized(self): RedisInstrumentor().uninstrument() @@ -64,12 +71,12 @@ def test_long_command_sanitized(self): span = spans[0] self._check_span(span, "MGET") self.assertTrue( - span.attributes.get(SpanAttributes.DB_STATEMENT).startswith( + span.attributes.get(DB_STATEMENT).startswith( "MGET ? ? ? ?" ) ) self.assertTrue( - span.attributes.get(SpanAttributes.DB_STATEMENT).endswith("...") + span.attributes.get(DB_STATEMENT).endswith("...") ) def test_long_command(self): @@ -80,12 +87,12 @@ def test_long_command(self): span = spans[0] self._check_span(span, "MGET") self.assertTrue( - span.attributes.get(SpanAttributes.DB_STATEMENT).startswith( + span.attributes.get(DB_STATEMENT).startswith( "MGET ? ? ? ?" ) ) self.assertTrue( - span.attributes.get(SpanAttributes.DB_STATEMENT).endswith("...") + span.attributes.get(DB_STATEMENT).endswith("...") ) def test_basics_sanitized(self): @@ -98,7 +105,7 @@ def test_basics_sanitized(self): span = spans[0] self._check_span(span, "GET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "GET ?" + span.attributes.get(DB_STATEMENT), "GET ?" ) self.assertEqual(span.attributes.get("db.redis.args_length"), 2) @@ -109,7 +116,7 @@ def test_basics(self): span = spans[0] self._check_span(span, "GET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "GET ?" + span.attributes.get(DB_STATEMENT), "GET ?" ) self.assertEqual(span.attributes.get("db.redis.args_length"), 2) @@ -128,7 +135,7 @@ def test_pipeline_traced_sanitized(self): span = spans[0] self._check_span(span, "SET RPUSH HGETALL") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SET ? ?\nRPUSH ? ?\nHGETALL ?", ) self.assertEqual(span.attributes.get("db.redis.pipeline_length"), 3) @@ -145,7 +152,7 @@ def test_pipeline_traced(self): span = spans[0] self._check_span(span, "SET RPUSH HGETALL") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SET ? ?\nRPUSH ? ?\nHGETALL ?", ) self.assertEqual(span.attributes.get("db.redis.pipeline_length"), 3) @@ -166,7 +173,7 @@ def test_pipeline_immediate_sanitized(self): span = spans[0] self._check_span(span, "SET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "SET ? ?" + span.attributes.get(DB_STATEMENT), "SET ? ?" ) def test_pipeline_immediate(self): @@ -182,7 +189,7 @@ def test_pipeline_immediate(self): span = spans[0] self._check_span(span, "SET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "SET ? ?" + span.attributes.get(DB_STATEMENT), "SET ? ?" ) def test_parent(self): @@ -230,7 +237,7 @@ def test_basics(self): span = spans[0] self._check_span(span, "GET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "GET ?" + span.attributes.get(DB_STATEMENT), "GET ?" ) self.assertEqual(span.attributes.get("db.redis.args_length"), 2) @@ -246,7 +253,7 @@ def test_pipeline_traced(self): span = spans[0] self._check_span(span, "SET RPUSH HGETALL") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SET ? ?\nRPUSH ? ?\nHGETALL ?", ) self.assertEqual(span.attributes.get("db.redis.pipeline_length"), 3) @@ -292,12 +299,12 @@ def _check_span(self, span, name): self.assertEqual(span.name, name) self.assertIs(span.status.status_code, trace.StatusCode.UNSET) self.assertEqual( - span.attributes.get(SpanAttributes.DB_REDIS_DATABASE_INDEX), 0 + span.attributes.get(DB_REDIS_DATABASE_INDEX), 0 ) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_NAME], "localhost" + span.attributes[NET_PEER_NAME], "localhost" ) - self.assertEqual(span.attributes[SpanAttributes.NET_PEER_PORT], 6379) + self.assertEqual(span.attributes[NET_PEER_PORT], 6379) def test_long_command(self): async_call(self.redis_client.mget(*range(1000))) @@ -307,12 +314,12 @@ def test_long_command(self): span = spans[0] self._check_span(span, "MGET") self.assertTrue( - span.attributes.get(SpanAttributes.DB_STATEMENT).startswith( + span.attributes.get(DB_STATEMENT).startswith( "MGET ? ? ? ?" ) ) self.assertTrue( - span.attributes.get(SpanAttributes.DB_STATEMENT).endswith("...") + span.attributes.get(DB_STATEMENT).endswith("...") ) def test_basics(self): @@ -322,7 +329,7 @@ def test_basics(self): span = spans[0] self._check_span(span, "GET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "GET ?" + span.attributes.get(DB_STATEMENT), "GET ?" ) self.assertEqual(span.attributes.get("db.redis.args_length"), 2) @@ -366,7 +373,7 @@ async def pipeline_simple(): span = spans[0] self._check_span(span, "SET RPUSH HGETALL") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SET ? ?\nRPUSH ? ?\nHGETALL ?", ) self.assertEqual(span.attributes.get("db.redis.pipeline_length"), 3) @@ -416,7 +423,7 @@ async def pipeline_immediate(): span = spans[0] self._check_span(span, "SET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "SET ? ?" + span.attributes.get(DB_STATEMENT), "SET ? ?" ) def test_pipeline_immediate_traced_full_time(self): @@ -491,7 +498,7 @@ def test_basics(self): span = spans[0] self._check_span(span, "GET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "GET ?" + span.attributes.get(DB_STATEMENT), "GET ?" ) self.assertEqual(span.attributes.get("db.redis.args_length"), 2) @@ -535,7 +542,7 @@ async def pipeline_simple(): span = spans[0] self._check_span(span, "SET RPUSH HGETALL") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SET ? ?\nRPUSH ? ?\nHGETALL ?", ) self.assertEqual(span.attributes.get("db.redis.pipeline_length"), 3) @@ -605,11 +612,11 @@ def _check_span(self, span, name): self.assertEqual(span.name, name) self.assertIs(span.status.status_code, trace.StatusCode.UNSET) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_NAME], "localhost" + span.attributes[NET_PEER_NAME], "localhost" ) - self.assertEqual(span.attributes[SpanAttributes.NET_PEER_PORT], 6379) + self.assertEqual(span.attributes[NET_PEER_PORT], 6379) self.assertEqual( - span.attributes[SpanAttributes.DB_REDIS_DATABASE_INDEX], 10 + span.attributes[DB_REDIS_DATABASE_INDEX], 10 ) def test_get(self): @@ -619,7 +626,7 @@ def test_get(self): span = spans[0] self._check_span(span, "GET") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), "GET ?" + span.attributes.get(DB_STATEMENT), "GET ?" ) diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/mixins.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/mixins.py index 57317b76c66..a1e542f23fd 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/mixins.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/mixins.py @@ -22,7 +22,11 @@ from opentelemetry import trace from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_STATEMENT, + DB_SYSTEM, +) from opentelemetry.test.test_base import TestBase Base = declarative_base() @@ -116,7 +120,7 @@ def _check_span(self, span, name): name = f"{name} {self.SQL_DB}" self.assertEqual(span.name, name) self.assertEqual( - span.attributes.get(SpanAttributes.DB_NAME), self.SQL_DB + span.attributes.get(DB_NAME), self.SQL_DB ) self.assertIs(span.status.status_code, trace.StatusCode.UNSET) self.assertGreater((span.end_time - span.start_time), 0) @@ -132,14 +136,14 @@ def test_orm_insert(self): self.assertEqual(len(spans), 2) span = spans[1] stmt = "INSERT INTO players (id, name) VALUES " - if span.attributes.get(SpanAttributes.DB_SYSTEM) == "sqlite": + if span.attributes.get(DB_SYSTEM) == "sqlite": stmt += "(?, ?)" else: stmt += "(%(id)s, %(name)s)" self._check_span(span, "INSERT") self.assertIn( "INSERT INTO players", - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), ) self.check_meta(span) @@ -153,14 +157,14 @@ def test_session_query(self): self.assertEqual(len(spans), 2) span = spans[1] stmt = "SELECT players.id AS players_id, players.name AS players_name \nFROM players \nWHERE players.name = " - if span.attributes.get(SpanAttributes.DB_SYSTEM) == "sqlite": + if span.attributes.get(DB_SYSTEM) == "sqlite": stmt += "?" else: stmt += "%(name_1)s" self._check_span(span, "SELECT") self.assertIn( "SELECT players.id AS players_id, players.name AS players_name \nFROM players \nWHERE players.name", - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), ) self.check_meta(span) @@ -177,7 +181,7 @@ def test_engine_connect_execute(self): span = spans[1] self._check_span(span, "SELECT") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SELECT * FROM players", ) self.check_meta(span) diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py index b92228c5cd1..96ed5e558b2 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py @@ -18,7 +18,15 @@ from sqlalchemy.exc import ProgrammingError from opentelemetry import trace -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_STATEMENT, + DB_USER, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from .mixins import Player, SQLAlchemyTestMixin @@ -48,19 +56,19 @@ class MssqlConnectorTestCase(SQLAlchemyTestMixin): def check_meta(self, span): # check database connection tags self.assertEqual( - span.attributes.get(SpanAttributes.NET_PEER_NAME), + span.attributes.get(NET_PEER_NAME), MSSQL_CONFIG["host"], ) self.assertEqual( - span.attributes.get(SpanAttributes.NET_PEER_PORT), + span.attributes.get(NET_PEER_PORT), MSSQL_CONFIG["port"], ) self.assertEqual( - span.attributes.get(SpanAttributes.DB_NAME), + span.attributes.get(DB_NAME), MSSQL_CONFIG["database"], ) self.assertEqual( - span.attributes.get(SpanAttributes.DB_USER), MSSQL_CONFIG["user"] + span.attributes.get(DB_USER), MSSQL_CONFIG["user"] ) def test_engine_execute_errors(self): @@ -77,11 +85,11 @@ def test_engine_execute_errors(self): # span fields self.assertEqual(span.name, "SELECT opentelemetry-tests") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SELECT * FROM a_wrong_table", ) self.assertEqual( - span.attributes.get(SpanAttributes.DB_NAME), self.SQL_DB + span.attributes.get(DB_NAME), self.SQL_DB ) self.check_meta(span) self.assertTrue(span.end_time - span.start_time > 0) @@ -106,6 +114,6 @@ def test_orm_insert(self): self._check_span(span, "INSERT") self.assertIn( "INSERT INTO players", - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), ) self.check_meta(span) diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mysql.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mysql.py index 6e4c85cd920..ca641c64028 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mysql.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mysql.py @@ -18,7 +18,15 @@ from sqlalchemy.exc import ProgrammingError from opentelemetry import trace -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_STATEMENT, + DB_USER, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from .mixins import SQLAlchemyTestMixin @@ -46,19 +54,19 @@ class MysqlConnectorTestCase(SQLAlchemyTestMixin): def check_meta(self, span): # check database connection tags self.assertEqual( - span.attributes.get(SpanAttributes.NET_PEER_NAME), + span.attributes.get(NET_PEER_NAME), MYSQL_CONFIG["host"], ) self.assertEqual( - span.attributes.get(SpanAttributes.NET_PEER_PORT), + span.attributes.get(NET_PEER_PORT), MYSQL_CONFIG["port"], ) self.assertEqual( - span.attributes.get(SpanAttributes.DB_NAME), + span.attributes.get(DB_NAME), MYSQL_CONFIG["database"], ) self.assertEqual( - span.attributes.get(SpanAttributes.DB_USER), MYSQL_CONFIG["user"] + span.attributes.get(DB_USER), MYSQL_CONFIG["user"] ) def test_engine_execute_errors(self): @@ -75,11 +83,11 @@ def test_engine_execute_errors(self): # span fields self.assertEqual(span.name, "SELECT opentelemetry-tests") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SELECT * FROM a_wrong_table", ) self.assertEqual( - span.attributes.get(SpanAttributes.DB_NAME), self.SQL_DB + span.attributes.get(DB_NAME), self.SQL_DB ) self.check_meta(span) self.assertTrue(span.end_time - span.start_time > 0) diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py index d0b659ec8b4..ada71513a3b 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py @@ -19,7 +19,14 @@ from sqlalchemy.exc import ProgrammingError from opentelemetry import trace -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_STATEMENT, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) from .mixins import SQLAlchemyTestMixin @@ -49,11 +56,11 @@ class PostgresTestCase(SQLAlchemyTestMixin): def check_meta(self, span): # check database connection tags self.assertEqual( - span.attributes.get(SpanAttributes.NET_PEER_NAME), + span.attributes.get(NET_PEER_NAME), POSTGRES_CONFIG["host"], ) self.assertEqual( - span.attributes.get(SpanAttributes.NET_PEER_PORT), + span.attributes.get(NET_PEER_PORT), POSTGRES_CONFIG["port"], ) @@ -70,11 +77,11 @@ def test_engine_execute_errors(self): # span fields self.assertEqual(span.name, "SELECT opentelemetry-tests") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SELECT * FROM a_wrong_table", ) self.assertEqual( - span.attributes.get(SpanAttributes.DB_NAME), self.SQL_DB + span.attributes.get(DB_NAME), self.SQL_DB ) self.check_meta(span) self.assertTrue(span.end_time - span.start_time > 0) diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_sqlite.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_sqlite.py index 884e3a37c28..02f875b22b4 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_sqlite.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_sqlite.py @@ -16,7 +16,10 @@ from sqlalchemy.exc import OperationalError from opentelemetry import trace -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_STATEMENT, +) from .mixins import SQLAlchemyTestMixin @@ -44,11 +47,11 @@ def test_engine_execute_errors(self): # span fields self.assertEqual(span.name, "SELECT :memory:") self.assertEqual( - span.attributes.get(SpanAttributes.DB_STATEMENT), + span.attributes.get(DB_STATEMENT), "SELECT * FROM a_wrong_table", ) self.assertEqual( - span.attributes.get(SpanAttributes.DB_NAME), self.SQL_DB + span.attributes.get(DB_NAME), self.SQL_DB ) self.assertTrue((span.end_time - span.start_time) > 0) # check the error From 3384f74bc8600b8a3a008d0ac43a265b7080f3af Mon Sep 17 00:00:00 2001 From: Keith Decker <47755047+keith-decker@users.noreply.github.com> Date: Fri, 20 Mar 2026 02:26:10 -0600 Subject: [PATCH 30/78] precommit formatting fixes (#4348) --- .../tests/asyncpg/test_asyncpg_functional.py | 92 +++++-------------- .../tests/celery/test_celery_functional.py | 76 ++++----------- .../tests/mysql/test_mysql_functional.py | 16 +--- .../tests/postgres/test_aiopg_functional.py | 40 ++------ .../tests/postgres/test_psycopg_functional.py | 20 +--- .../tests/pymongo/test_pymongo_functional.py | 12 +-- .../tests/pymysql/test_pymysql_functional.py | 16 +--- .../tests/redis/test_redis_functional.py | 84 +++++------------ .../tests/sqlalchemy_tests/mixins.py | 4 +- .../tests/sqlalchemy_tests/test_mssql.py | 8 +- .../tests/sqlalchemy_tests/test_mysql.py | 8 +- .../tests/sqlalchemy_tests/test_postgres.py | 4 +- .../tests/sqlalchemy_tests/test_sqlite.py | 4 +- 13 files changed, 93 insertions(+), 291 deletions(-) diff --git a/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py b/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py index 8242353ae7a..6a2499fdb48 100644 --- a/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py +++ b/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py @@ -40,21 +40,11 @@ def async_call(coro): class CheckSpanMixin: def check_span(self, span, expected_db_name=POSTGRES_DB_NAME): - self.assertEqual( - span.attributes[DB_SYSTEM], "postgresql" - ) - self.assertEqual( - span.attributes[DB_NAME], expected_db_name - ) - self.assertEqual( - span.attributes[DB_USER], POSTGRES_USER - ) - self.assertEqual( - span.attributes[NET_PEER_NAME], POSTGRES_HOST - ) - self.assertEqual( - span.attributes[NET_PEER_PORT], POSTGRES_PORT - ) + self.assertEqual(span.attributes[DB_SYSTEM], "postgresql") + self.assertEqual(span.attributes[DB_NAME], expected_db_name) + self.assertEqual(span.attributes[DB_USER], POSTGRES_USER) + self.assertEqual(span.attributes[NET_PEER_NAME], POSTGRES_HOST) + self.assertEqual(span.attributes[NET_PEER_PORT], POSTGRES_PORT) class TestFunctionalAsyncPG(TestBase, CheckSpanMixin): @@ -84,9 +74,7 @@ def test_instrumented_execute_method_without_arguments(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT 42;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT 42;") def test_instrumented_execute_method_error(self, *_, **__): """Should create an error span for execute() with the database name as the span name.""" @@ -107,9 +95,7 @@ def test_instrumented_fetch_method_without_arguments(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT 42;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT 42;") def test_instrumented_fetch_method_empty_query(self, *_, **__): """Should create an error span for fetch() with the database name as the span name.""" @@ -129,9 +115,7 @@ def test_instrumented_fetchval_method_without_arguments(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT 42;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT 42;") def test_instrumented_fetchval_method_empty_query(self, *_, **__): """Should create an error span for fetchval() with the database name as the span name.""" @@ -151,9 +135,7 @@ def test_instrumented_fetchrow_method_without_arguments(self, *_, **__): self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT 42;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT 42;") def test_instrumented_fetchrow_method_empty_query(self, *_, **__): """Should create an error span for fetchrow() with the database name as the span name.""" @@ -182,9 +164,7 @@ async def _cursor_execute(): self.check_span(spans[0]) self.assertEqual(spans[0].name, "BEGIN;") - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "BEGIN;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "BEGIN;") self.assertIs(StatusCode.UNSET, spans[0].status.status_code) for span in spans[1:-1]: @@ -198,9 +178,7 @@ async def _cursor_execute(): self.check_span(spans[-1]) self.assertEqual(spans[-1].name, "COMMIT;") - self.assertEqual( - spans[-1].attributes[DB_STATEMENT], "COMMIT;" - ) + self.assertEqual(spans[-1].attributes[DB_STATEMENT], "COMMIT;") def test_instrumented_cursor_execute_method_empty_query(self, *_, **__): """Should create spans for the transaction and cursor fetches with the database name as the span name.""" @@ -215,9 +193,7 @@ async def _cursor_execute(): self.assertEqual(len(spans), 3) self.check_span(spans[0]) - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "BEGIN;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "BEGIN;") self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[1]) @@ -226,9 +202,7 @@ async def _cursor_execute(): self.assertIs(StatusCode.UNSET, spans[1].status.status_code) self.check_span(spans[2]) - self.assertEqual( - spans[2].attributes[DB_STATEMENT], "COMMIT;" - ) + self.assertEqual(spans[2].attributes[DB_STATEMENT], "COMMIT;") def test_instrumented_remove_comments(self, *_, **__): """Should remove comments from the query and set the span name correctly.""" @@ -275,21 +249,15 @@ async def _transaction_execute(): spans = self.memory_exporter.get_finished_spans() self.assertEqual(3, len(spans)) self.check_span(spans[0]) - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "BEGIN;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "BEGIN;") self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[1]) - self.assertEqual( - spans[1].attributes[DB_STATEMENT], "SELECT 42;" - ) + self.assertEqual(spans[1].attributes[DB_STATEMENT], "SELECT 42;") self.assertIs(StatusCode.UNSET, spans[1].status.status_code) self.check_span(spans[2]) - self.assertEqual( - spans[2].attributes[DB_STATEMENT], "COMMIT;" - ) + self.assertEqual(spans[2].attributes[DB_STATEMENT], "COMMIT;") self.assertIs(StatusCode.UNSET, spans[2].status.status_code) def test_instrumented_failed_transaction_method(self, *_, **__): @@ -306,9 +274,7 @@ async def _transaction_execute(): self.assertEqual(3, len(spans)) self.check_span(spans[0]) - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "BEGIN;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "BEGIN;") self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[1]) @@ -319,9 +285,7 @@ async def _transaction_execute(): self.assertEqual(StatusCode.ERROR, spans[1].status.status_code) self.check_span(spans[2]) - self.assertEqual( - spans[2].attributes[DB_STATEMENT], "ROLLBACK;" - ) + self.assertEqual(spans[2].attributes[DB_STATEMENT], "ROLLBACK;") self.assertIs(StatusCode.UNSET, spans[2].status.status_code) def test_instrumented_method_doesnt_capture_parameters(self, *_, **__): @@ -331,9 +295,7 @@ def test_instrumented_method_doesnt_capture_parameters(self, *_, **__): self.assertEqual(len(spans), 1) self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT $1;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT $1;") class TestFunctionalAsyncPG_CaptureParameters(TestBase, CheckSpanMixin): @@ -366,9 +328,7 @@ def test_instrumented_execute_method_with_arguments(self, *_, **__): self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT $1;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT $1;") self.assertEqual( spans[0].attributes["db.statement.parameters"], "('1',)" ) @@ -381,9 +341,7 @@ def test_instrumented_fetch_method_with_arguments(self, *_, **__): self.check_span(spans[0]) self.assertEqual(spans[0].name, "SELECT") - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT $1;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT $1;") self.assertEqual( spans[0].attributes["db.statement.parameters"], "('1',)" ) @@ -395,9 +353,7 @@ def test_instrumented_executemany_method_with_arguments(self, *_, **__): self.assertEqual(len(spans), 1) self.assertIs(StatusCode.UNSET, spans[0].status.status_code) self.check_span(spans[0]) - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT $1;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT $1;") self.assertEqual( spans[0].attributes["db.statement.parameters"], "([['1'], ['2']],)" ) @@ -410,9 +366,7 @@ def test_instrumented_execute_interface_error_method(self, *_, **__): self.assertEqual(len(spans), 1) self.assertIs(StatusCode.ERROR, spans[0].status.status_code) self.check_span(spans[0]) - self.assertEqual( - spans[0].attributes[DB_STATEMENT], "SELECT 42;" - ) + self.assertEqual(spans[0].attributes[DB_STATEMENT], "SELECT 42;") self.assertEqual( spans[0].attributes["db.statement.parameters"], "(1, 2, 3)" ) diff --git a/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py b/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py index cf030e1e048..b1b17204ece 100644 --- a/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py +++ b/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py @@ -111,9 +111,7 @@ def fn_task(): assert span.status.is_ok is True assert span.name == "run/test_celery_functional.fn_task" - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) == t.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == t.task_id assert ( span.attributes.get("celery.task_name") == "test_celery_functional.fn_task" @@ -138,9 +136,7 @@ def fn_task(self): assert span.status.is_ok is True assert span.name == "run/test_celery_functional.fn_task" - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) == t.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == t.task_id assert ( span.attributes.get("celery.task_name") == "test_celery_functional.fn_task" @@ -173,10 +169,7 @@ def fn_task_parameters(user, force_logout=False): == "apply_async/test_celery_functional.fn_task_parameters" ) assert async_span.attributes.get("celery.action") == "apply_async" - assert ( - async_span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert async_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id assert ( async_span.attributes.get("celery.task_name") == "test_celery_functional.fn_task_parameters" @@ -186,10 +179,7 @@ def fn_task_parameters(user, force_logout=False): assert run_span.name == "test_celery_functional.fn_task_parameters" assert run_span.attributes.get("celery.action") == "run" assert run_span.attributes.get("celery.state") == "SUCCESS" - assert ( - run_span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert run_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id assert ( run_span.attributes.get("celery.task_name") == "test_celery_functional.fn_task_parameters" @@ -234,10 +224,7 @@ def fn_task_parameters(user, force_logout=False): == "apply_async/test_celery_functional.fn_task_parameters" ) assert async_span.attributes.get("celery.action") == "apply_async" - assert ( - async_span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert async_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id assert ( async_span.attributes.get("celery.task_name") == "test_celery_functional.fn_task_parameters" @@ -247,10 +234,7 @@ def fn_task_parameters(user, force_logout=False): assert run_span.name == "run/test_celery_functional.fn_task_parameters" assert run_span.attributes.get("celery.action") == "run" assert run_span.attributes.get("celery.state") == "SUCCESS" - assert ( - run_span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert run_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id assert ( run_span.attributes.get("celery.task_name") == "test_celery_functional.fn_task_parameters" @@ -287,10 +271,7 @@ def fn_exception(): assert event.name == "exception" assert event.attributes[EXCEPTION_TYPE] == "Exception" assert EXCEPTION_MESSAGE in event.attributes - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id assert "Task class is failing" in span.status.description @@ -318,10 +299,7 @@ def fn_exception(): span.attributes.get("celery.task_name") == "test_celery_functional.fn_exception" ) - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id def test_fn_retry_exception(celery_app, memory_exporter): @@ -348,10 +326,7 @@ def fn_exception(): span.attributes.get("celery.task_name") == "test_celery_functional.fn_exception" ) - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id def test_class_task(celery_app, memory_exporter): @@ -383,10 +358,7 @@ def run(self): ) assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "SUCCESS" - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id def test_class_task_exception(celery_app, memory_exporter): @@ -419,10 +391,7 @@ def run(self): assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "FAILURE" assert span.status.status_code == StatusCode.ERROR - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id assert "Task class is failing" in span.status.description @@ -454,10 +423,7 @@ def run(self): assert span.name == "run/test_celery_functional.BaseTask" assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "FAILURE" - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id def test_shared_task(celery_app, memory_exporter): @@ -482,10 +448,7 @@ def add(x, y): ) assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "SUCCESS" - assert ( - span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id @mark.skip(reason="inconsistent test results") @@ -532,10 +495,7 @@ class CelerySubClass(CelerySuperClass): ) assert run_span.attributes.get("celery.action") == "run" assert run_span.attributes.get("celery.state") == "SUCCESS" - assert ( - run_span.attributes.get(MESSAGING_MESSAGE_ID) - == result.task_id - ) + assert run_span.attributes.get(MESSAGING_MESSAGE_ID) == result.task_id assert async_run_span.status.is_ok is True assert async_run_span.name == "run/test_celery_functional.CelerySubClass" @@ -546,8 +506,7 @@ class CelerySubClass(CelerySuperClass): assert async_run_span.attributes.get("celery.action") == "run" assert async_run_span.attributes.get("celery.state") == "SUCCESS" assert ( - async_run_span.attributes.get(MESSAGING_MESSAGE_ID) - != result.task_id + async_run_span.attributes.get(MESSAGING_MESSAGE_ID) != result.task_id ) assert async_span.status.is_ok is True @@ -559,10 +518,7 @@ class CelerySubClass(CelerySuperClass): == "test_celery_functional.CelerySubClass" ) assert async_span.attributes.get("celery.action") == "apply_async" - assert ( - async_span.attributes.get(MESSAGING_MESSAGE_ID) - != result.task_id - ) + assert async_span.attributes.get(MESSAGING_MESSAGE_ID) != result.task_id assert async_span.attributes.get( MESSAGING_MESSAGE_ID ) == async_run_span.attributes.get(MESSAGING_MESSAGE_ID) diff --git a/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py b/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py index 105cca0fa46..30bcc6a2982 100644 --- a/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py +++ b/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py @@ -74,18 +74,10 @@ def validate_spans(self, span_name): self.assertIs(db_span.parent, root_span.get_span_context()) self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT) self.assertEqual(db_span.attributes[DB_SYSTEM], "mysql") - self.assertEqual( - db_span.attributes[DB_NAME], MYSQL_DB_NAME - ) - self.assertEqual( - db_span.attributes[DB_USER], MYSQL_USER - ) - self.assertEqual( - db_span.attributes[NET_PEER_NAME], MYSQL_HOST - ) - self.assertEqual( - db_span.attributes[NET_PEER_PORT], MYSQL_PORT - ) + self.assertEqual(db_span.attributes[DB_NAME], MYSQL_DB_NAME) + self.assertEqual(db_span.attributes[DB_USER], MYSQL_USER) + self.assertEqual(db_span.attributes[NET_PEER_NAME], MYSQL_HOST) + self.assertEqual(db_span.attributes[NET_PEER_PORT], MYSQL_PORT) def test_execute(self): """Should create a child span for execute""" diff --git a/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py b/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py index 84ff4e891f4..437a4332f13 100644 --- a/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py +++ b/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py @@ -82,21 +82,11 @@ def validate_spans(self, span_name): self.assertIsNotNone(child_span.parent) self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) - self.assertEqual( - child_span.attributes[DB_SYSTEM], "postgresql" - ) - self.assertEqual( - child_span.attributes[DB_NAME], POSTGRES_DB_NAME - ) - self.assertEqual( - child_span.attributes[DB_USER], POSTGRES_USER - ) - self.assertEqual( - child_span.attributes[NET_PEER_NAME], POSTGRES_HOST - ) - self.assertEqual( - child_span.attributes[NET_PEER_PORT], POSTGRES_PORT - ) + self.assertEqual(child_span.attributes[DB_SYSTEM], "postgresql") + self.assertEqual(child_span.attributes[DB_NAME], POSTGRES_DB_NAME) + self.assertEqual(child_span.attributes[DB_USER], POSTGRES_USER) + self.assertEqual(child_span.attributes[NET_PEER_NAME], POSTGRES_HOST) + self.assertEqual(child_span.attributes[NET_PEER_PORT], POSTGRES_PORT) def test_execute(self): """Should create a child span for execute method""" @@ -169,21 +159,11 @@ def validate_spans(self, span_name): self.assertIsNotNone(child_span.parent) self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) - self.assertEqual( - child_span.attributes[DB_SYSTEM], "postgresql" - ) - self.assertEqual( - child_span.attributes[DB_NAME], POSTGRES_DB_NAME - ) - self.assertEqual( - child_span.attributes[DB_USER], POSTGRES_USER - ) - self.assertEqual( - child_span.attributes[NET_PEER_NAME], POSTGRES_HOST - ) - self.assertEqual( - child_span.attributes[NET_PEER_PORT], POSTGRES_PORT - ) + self.assertEqual(child_span.attributes[DB_SYSTEM], "postgresql") + self.assertEqual(child_span.attributes[DB_NAME], POSTGRES_DB_NAME) + self.assertEqual(child_span.attributes[DB_USER], POSTGRES_USER) + self.assertEqual(child_span.attributes[NET_PEER_NAME], POSTGRES_HOST) + self.assertEqual(child_span.attributes[NET_PEER_PORT], POSTGRES_PORT) def test_execute(self): """Should create a child span for execute method""" diff --git a/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py b/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py index ab7bcad6500..6cc800dd047 100644 --- a/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py +++ b/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py @@ -76,21 +76,11 @@ def validate_spans(self, span_name): self.assertIsNotNone(child_span.parent) self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) - self.assertEqual( - child_span.attributes[DB_SYSTEM], "postgresql" - ) - self.assertEqual( - child_span.attributes[DB_NAME], POSTGRES_DB_NAME - ) - self.assertEqual( - child_span.attributes[DB_USER], POSTGRES_USER - ) - self.assertEqual( - child_span.attributes[NET_PEER_NAME], POSTGRES_HOST - ) - self.assertEqual( - child_span.attributes[NET_PEER_PORT], POSTGRES_PORT - ) + self.assertEqual(child_span.attributes[DB_SYSTEM], "postgresql") + self.assertEqual(child_span.attributes[DB_NAME], POSTGRES_DB_NAME) + self.assertEqual(child_span.attributes[DB_USER], POSTGRES_USER) + self.assertEqual(child_span.attributes[NET_PEER_NAME], POSTGRES_HOST) + self.assertEqual(child_span.attributes[NET_PEER_PORT], POSTGRES_PORT) def test_execute(self): """Should create a child span for execute method""" diff --git a/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py b/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py index bd157a01884..94745a76920 100644 --- a/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py +++ b/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py @@ -68,15 +68,9 @@ def validate_spans(self, expected_db_statement): self.assertIsNotNone(pymongo_span.parent) self.assertIs(pymongo_span.parent, root_span.get_span_context()) self.assertIs(pymongo_span.kind, trace_api.SpanKind.CLIENT) - self.assertEqual( - pymongo_span.attributes[DB_NAME], MONGODB_DB_NAME - ) - self.assertEqual( - pymongo_span.attributes[NET_PEER_NAME], MONGODB_HOST - ) - self.assertEqual( - pymongo_span.attributes[NET_PEER_PORT], MONGODB_PORT - ) + self.assertEqual(pymongo_span.attributes[DB_NAME], MONGODB_DB_NAME) + self.assertEqual(pymongo_span.attributes[NET_PEER_NAME], MONGODB_HOST) + self.assertEqual(pymongo_span.attributes[NET_PEER_PORT], MONGODB_PORT) self.assertEqual( pymongo_span.attributes[DB_MONGODB_COLLECTION], MONGODB_COLLECTION_NAME, diff --git a/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py b/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py index dfcf4f2f184..e33b6c0f88c 100644 --- a/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py +++ b/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py @@ -74,18 +74,10 @@ def validate_spans(self, span_name): self.assertIs(db_span.parent, root_span.get_span_context()) self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT) self.assertEqual(db_span.attributes[DB_SYSTEM], "mysql") - self.assertEqual( - db_span.attributes[DB_NAME], MYSQL_DB_NAME - ) - self.assertEqual( - db_span.attributes[DB_USER], MYSQL_USER - ) - self.assertEqual( - db_span.attributes[NET_PEER_NAME], MYSQL_HOST - ) - self.assertEqual( - db_span.attributes[NET_PEER_PORT], MYSQL_PORT - ) + self.assertEqual(db_span.attributes[DB_NAME], MYSQL_DB_NAME) + self.assertEqual(db_span.attributes[DB_USER], MYSQL_USER) + self.assertEqual(db_span.attributes[NET_PEER_NAME], MYSQL_HOST) + self.assertEqual(db_span.attributes[NET_PEER_PORT], MYSQL_PORT) def test_execute(self): """Should create a child span for execute""" diff --git a/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py b/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py index f518244ac22..ed791033696 100644 --- a/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py +++ b/tests/opentelemetry-docker-tests/tests/redis/test_redis_functional.py @@ -52,12 +52,8 @@ def tearDown(self): def _check_span(self, span, name): self.assertEqual(span.name, name) self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqual( - span.attributes.get(DB_REDIS_DATABASE_INDEX), 0 - ) - self.assertEqual( - span.attributes[NET_PEER_NAME], "localhost" - ) + self.assertEqual(span.attributes.get(DB_REDIS_DATABASE_INDEX), 0) + self.assertEqual(span.attributes[NET_PEER_NAME], "localhost") self.assertEqual(span.attributes[NET_PEER_PORT], 6379) def test_long_command_sanitized(self): @@ -71,13 +67,9 @@ def test_long_command_sanitized(self): span = spans[0] self._check_span(span, "MGET") self.assertTrue( - span.attributes.get(DB_STATEMENT).startswith( - "MGET ? ? ? ?" - ) - ) - self.assertTrue( - span.attributes.get(DB_STATEMENT).endswith("...") + span.attributes.get(DB_STATEMENT).startswith("MGET ? ? ? ?") ) + self.assertTrue(span.attributes.get(DB_STATEMENT).endswith("...")) def test_long_command(self): self.redis_client.mget(*range(1000)) @@ -87,13 +79,9 @@ def test_long_command(self): span = spans[0] self._check_span(span, "MGET") self.assertTrue( - span.attributes.get(DB_STATEMENT).startswith( - "MGET ? ? ? ?" - ) - ) - self.assertTrue( - span.attributes.get(DB_STATEMENT).endswith("...") + span.attributes.get(DB_STATEMENT).startswith("MGET ? ? ? ?") ) + self.assertTrue(span.attributes.get(DB_STATEMENT).endswith("...")) def test_basics_sanitized(self): RedisInstrumentor().uninstrument() @@ -104,9 +92,7 @@ def test_basics_sanitized(self): self.assertEqual(len(spans), 1) span = spans[0] self._check_span(span, "GET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "GET ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "GET ?") self.assertEqual(span.attributes.get("db.redis.args_length"), 2) def test_basics(self): @@ -115,9 +101,7 @@ def test_basics(self): self.assertEqual(len(spans), 1) span = spans[0] self._check_span(span, "GET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "GET ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "GET ?") self.assertEqual(span.attributes.get("db.redis.args_length"), 2) def test_pipeline_traced_sanitized(self): @@ -172,9 +156,7 @@ def test_pipeline_immediate_sanitized(self): self.assertEqual(len(spans), 2) span = spans[0] self._check_span(span, "SET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "SET ? ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "SET ? ?") def test_pipeline_immediate(self): with self.redis_client.pipeline() as pipeline: @@ -188,9 +170,7 @@ def test_pipeline_immediate(self): self.assertEqual(len(spans), 2) span = spans[0] self._check_span(span, "SET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "SET ? ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "SET ? ?") def test_parent(self): """Ensure OpenTelemetry works with redis.""" @@ -236,9 +216,7 @@ def test_basics(self): self.assertEqual(len(spans), 1) span = spans[0] self._check_span(span, "GET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "GET ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "GET ?") self.assertEqual(span.attributes.get("db.redis.args_length"), 2) def test_pipeline_traced(self): @@ -298,12 +276,8 @@ def tearDown(self): def _check_span(self, span, name): self.assertEqual(span.name, name) self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqual( - span.attributes.get(DB_REDIS_DATABASE_INDEX), 0 - ) - self.assertEqual( - span.attributes[NET_PEER_NAME], "localhost" - ) + self.assertEqual(span.attributes.get(DB_REDIS_DATABASE_INDEX), 0) + self.assertEqual(span.attributes[NET_PEER_NAME], "localhost") self.assertEqual(span.attributes[NET_PEER_PORT], 6379) def test_long_command(self): @@ -314,13 +288,9 @@ def test_long_command(self): span = spans[0] self._check_span(span, "MGET") self.assertTrue( - span.attributes.get(DB_STATEMENT).startswith( - "MGET ? ? ? ?" - ) - ) - self.assertTrue( - span.attributes.get(DB_STATEMENT).endswith("...") + span.attributes.get(DB_STATEMENT).startswith("MGET ? ? ? ?") ) + self.assertTrue(span.attributes.get(DB_STATEMENT).endswith("...")) def test_basics(self): self.assertIsNone(async_call(self.redis_client.get("cheese"))) @@ -328,9 +298,7 @@ def test_basics(self): self.assertEqual(len(spans), 1) span = spans[0] self._check_span(span, "GET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "GET ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "GET ?") self.assertEqual(span.attributes.get("db.redis.args_length"), 2) def test_execute_command_traced_full_time(self): @@ -422,9 +390,7 @@ async def pipeline_immediate(): self.assertEqual(len(spans), 2) span = spans[0] self._check_span(span, "SET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "SET ? ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "SET ? ?") def test_pipeline_immediate_traced_full_time(self): """Command should be traced for coroutine execution time, not creation time.""" @@ -497,9 +463,7 @@ def test_basics(self): self.assertEqual(len(spans), 1) span = spans[0] self._check_span(span, "GET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "GET ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "GET ?") self.assertEqual(span.attributes.get("db.redis.args_length"), 2) def test_execute_command_traced_full_time(self): @@ -611,13 +575,9 @@ def tearDown(self): def _check_span(self, span, name): self.assertEqual(span.name, name) self.assertIs(span.status.status_code, trace.StatusCode.UNSET) - self.assertEqual( - span.attributes[NET_PEER_NAME], "localhost" - ) + self.assertEqual(span.attributes[NET_PEER_NAME], "localhost") self.assertEqual(span.attributes[NET_PEER_PORT], 6379) - self.assertEqual( - span.attributes[DB_REDIS_DATABASE_INDEX], 10 - ) + self.assertEqual(span.attributes[DB_REDIS_DATABASE_INDEX], 10) def test_get(self): self.assertIsNone(self.redis_client.get("foo")) @@ -625,9 +585,7 @@ def test_get(self): self.assertEqual(len(spans), 1) span = spans[0] self._check_span(span, "GET") - self.assertEqual( - span.attributes.get(DB_STATEMENT), "GET ?" - ) + self.assertEqual(span.attributes.get(DB_STATEMENT), "GET ?") class TestRedisearchInstrument(TestBase): diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/mixins.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/mixins.py index a1e542f23fd..2fda9931413 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/mixins.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/mixins.py @@ -119,9 +119,7 @@ def _check_span(self, span, name): if self.SQL_DB: name = f"{name} {self.SQL_DB}" self.assertEqual(span.name, name) - self.assertEqual( - span.attributes.get(DB_NAME), self.SQL_DB - ) + self.assertEqual(span.attributes.get(DB_NAME), self.SQL_DB) self.assertIs(span.status.status_code, trace.StatusCode.UNSET) self.assertGreater((span.end_time - span.start_time), 0) diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py index 96ed5e558b2..ce2feeaf2dc 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mssql.py @@ -67,9 +67,7 @@ def check_meta(self, span): span.attributes.get(DB_NAME), MSSQL_CONFIG["database"], ) - self.assertEqual( - span.attributes.get(DB_USER), MSSQL_CONFIG["user"] - ) + self.assertEqual(span.attributes.get(DB_USER), MSSQL_CONFIG["user"]) def test_engine_execute_errors(self): # ensures that SQL errors are reported @@ -88,9 +86,7 @@ def test_engine_execute_errors(self): span.attributes.get(DB_STATEMENT), "SELECT * FROM a_wrong_table", ) - self.assertEqual( - span.attributes.get(DB_NAME), self.SQL_DB - ) + self.assertEqual(span.attributes.get(DB_NAME), self.SQL_DB) self.check_meta(span) self.assertTrue(span.end_time - span.start_time > 0) # check the error diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mysql.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mysql.py index ca641c64028..a6e259c103e 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mysql.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_mysql.py @@ -65,9 +65,7 @@ def check_meta(self, span): span.attributes.get(DB_NAME), MYSQL_CONFIG["database"], ) - self.assertEqual( - span.attributes.get(DB_USER), MYSQL_CONFIG["user"] - ) + self.assertEqual(span.attributes.get(DB_USER), MYSQL_CONFIG["user"]) def test_engine_execute_errors(self): # ensures that SQL errors are reported @@ -86,9 +84,7 @@ def test_engine_execute_errors(self): span.attributes.get(DB_STATEMENT), "SELECT * FROM a_wrong_table", ) - self.assertEqual( - span.attributes.get(DB_NAME), self.SQL_DB - ) + self.assertEqual(span.attributes.get(DB_NAME), self.SQL_DB) self.check_meta(span) self.assertTrue(span.end_time - span.start_time > 0) # check the error diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py index ada71513a3b..a384bbe8cc4 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py @@ -80,9 +80,7 @@ def test_engine_execute_errors(self): span.attributes.get(DB_STATEMENT), "SELECT * FROM a_wrong_table", ) - self.assertEqual( - span.attributes.get(DB_NAME), self.SQL_DB - ) + self.assertEqual(span.attributes.get(DB_NAME), self.SQL_DB) self.check_meta(span) self.assertTrue(span.end_time - span.start_time > 0) # check the error diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_sqlite.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_sqlite.py index 02f875b22b4..357970ba77f 100644 --- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_sqlite.py +++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_sqlite.py @@ -50,9 +50,7 @@ def test_engine_execute_errors(self): span.attributes.get(DB_STATEMENT), "SELECT * FROM a_wrong_table", ) - self.assertEqual( - span.attributes.get(DB_NAME), self.SQL_DB - ) + self.assertEqual(span.attributes.get(DB_NAME), self.SQL_DB) self.assertTrue((span.end_time - span.start_time) > 0) # check the error self.assertIs( From 6fb491860146ce4331e1fde69e789c67133a3aeb Mon Sep 17 00:00:00 2001 From: Kelsey Ma Date: Fri, 20 Mar 2026 01:35:43 -0700 Subject: [PATCH 31/78] Update OpAMP client to have additional callback methods (#4322) * Update callbacks to use format similar to existing java and go clients * Add changelog entry * Update Callbacks to use ABC, add MessageData class and ReportFullState flag handling * Fix docs build * Check error_response before processing other ServerToAgent fields per OpAMP spec --------- Co-authored-by: Riccardo Magliocchetti --- docs/conf.py | 4 + opamp/opentelemetry-opamp-client/CHANGELOG.md | 2 + .../src/opentelemetry/_opamp/__init__.py | 18 +- .../src/opentelemetry/_opamp/agent.py | 64 ++++- .../src/opentelemetry/_opamp/callbacks.py | 94 +++++++ .../_opamp/transport/requests.py | 3 +- ...config_status_heartbeat_disconnection.yaml | 12 +- .../tests/opamp/test_agent.py | 262 +++++++++++++++--- .../tests/opamp/test_callbacks.py | 36 +++ .../tests/opamp/test_e2e.py | 51 ++-- 10 files changed, 463 insertions(+), 83 deletions(-) create mode 100644 opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/callbacks.py create mode 100644 opamp/opentelemetry-opamp-client/tests/opamp/test_callbacks.py diff --git a/docs/conf.py b/docs/conf.py index b4e57200fb9..df62d5c15a4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -160,6 +160,10 @@ "py:class", "opamp_pb2.EffectiveConfig", ), + ( + "py:class", + "opamp_pb2.AgentRemoteConfig", + ), ] cfg = ConfigParser() diff --git a/opamp/opentelemetry-opamp-client/CHANGELOG.md b/opamp/opentelemetry-opamp-client/CHANGELOG.md index 6e312367062..f981e2dcf39 100644 --- a/opamp/opentelemetry-opamp-client/CHANGELOG.md +++ b/opamp/opentelemetry-opamp-client/CHANGELOG.md @@ -9,3 +9,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial implementation ([#3635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3635)) +- Update client to have additional callback methods + ([#4322](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4322)) diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py index 571a9837a32..ed85131f047 100644 --- a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py @@ -35,7 +35,7 @@ Since OpAMP APIs, config options or environment variables are not standardizes the distros are required to provide code doing so. -OTel Python distros would need to provide their own message handler callback that implements the actual +OTel Python distros would need to provide their own Callbacks subclass that implements the actual change of whatever configuration their backends sends. Please note that the API is not finalized yet and so the name is called ``_opamp`` with the underscore. @@ -48,15 +48,18 @@ import os from opentelemetry._opamp.agent import OpAMPAgent + from opentelemetry._opamp.callbacks import Callbacks from opentelemetry._opamp.client import OpAMPClient - from opentelemetry._opamp.proto import opamp_pb2 as opamp_pb2 from opentelemetry.sdk._configuration import _OTelSDKConfigurator from opentelemetry.sdk.resources import OTELResourceDetector - def opamp_handler(agent: OpAMPAgent, client: OpAMPClient, message: opamp_pb2.ServerToAgent): - for config_filename, config in message.remote_config.config.config_map.items(): - print("do something") + class MyCallbacks(Callbacks): + def on_message(self, agent, client, message): + if message.remote_config is None: + return + for config_filename, config in message.remote_config.config.config_map.items(): + print("do something") class MyOpenTelemetryConfigurator(_OTelSDKConfigurator): @@ -79,7 +82,7 @@ def _configure(self, **kwargs): ) opamp_agent = OpAMPAgent( interval=30, - message_handler=opamp_handler, + callbacks=MyCallbacks(), client=opamp_client, ) opamp_agent.start() @@ -90,6 +93,7 @@ def _configure(self, **kwargs): """ from opentelemetry._opamp.agent import OpAMPAgent +from opentelemetry._opamp.callbacks import Callbacks, MessageData from opentelemetry._opamp.client import OpAMPClient -__all__ = ["OpAMPAgent", "OpAMPClient"] +__all__ = ["Callbacks", "MessageData", "OpAMPAgent", "OpAMPClient"] diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py index fe547c81c91..2616726fcce 100644 --- a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py @@ -21,12 +21,24 @@ import threading from typing import Any, Callable +from opentelemetry._opamp.callbacks import Callbacks, MessageData from opentelemetry._opamp.client import OpAMPClient from opentelemetry._opamp.proto import opamp_pb2 logger = logging.getLogger(__name__) +def _safe_invoke(function: Callable[..., Any], *args: Any) -> None: + function_name = "" + try: + function_name = function.__name__ + function(*args) + except Exception as exc: # pylint: disable=broad-exception-caught + logger.error( + "Error when invoking function '%s'", function_name, exc_info=exc + ) + + class _Job: """ Represents a single request job, with retry/backoff metadata. @@ -73,9 +85,7 @@ def __init__( self, *, interval: float = 30, - message_handler: Callable[ - ["OpAMPAgent", OpAMPClient, opamp_pb2.ServerToAgent], None - ], + callbacks: Callbacks, max_retries: int = 10, heartbeat_max_retries: int = 1, initial_backoff: float = 1.0, @@ -83,14 +93,14 @@ def __init__( ): """ :param interval: seconds between heartbeat calls - :param message_handler: user provided function that takes the received ServerToAgent message + :param callbacks: Callbacks instance for receiving client events :param max_retries: how many times to retry a failed job for ad-hoc messages :param heartbeat_max_retries: how many times to retry an heartbeat failed job :param initial_backoff: base seconds for exponential backoff :param client: an OpAMPClient instance """ self._interval = interval - self._handler = message_handler + self._callbacks = callbacks self._max_retries = max_retries self._heartbeat_max_retries = heartbeat_max_retries self._initial_backoff = initial_backoff @@ -186,15 +196,24 @@ def _run_worker(self) -> None: while job.should_retry() and not self._stop.is_set(): try: message = self._client.send(job.payload) + _safe_invoke( + self._callbacks.on_connect, self, self._client + ) logger.debug("Job succeeded: %r", job.payload) break except Exception as exc: job.attempt += 1 + _safe_invoke( + self._callbacks.on_connect_failed, + self, + self._client, + exc, + ) logger.warning( "Job %r failed attempt %d/%d: %s", job.payload, job.attempt, - job.max_retries, + job.max_retries + 1, exc, ) @@ -202,7 +221,6 @@ def _run_worker(self) -> None: logger.error( "Job %r dropped after max retries", job.payload ) - logger.exception(exc) break # exponential backoff with +/- 20% jitter, interruptible by stop event @@ -216,14 +234,7 @@ def _run_worker(self) -> None: break if message is not None: - # we can't do much if the handler fails other than logging - try: - self._handler(self, self._client, message) - logger.debug("Called Job message handler for: %r", message) - except Exception as exc: - logger.warning( - "Job %r handler failed with: %s", job.payload, exc - ) + self._process_message(message) try: if job.callback is not None: @@ -233,6 +244,29 @@ def _run_worker(self) -> None: finally: self._queue.task_done() + def _process_message(self, message: opamp_pb2.ServerToAgent) -> None: + if message.HasField("error_response"): + _safe_invoke( + self._callbacks.on_error, + self, + self._client, + message.error_response, + ) + return + + if message.flags & opamp_pb2.ServerToAgentFlags_ReportFullState: + logger.debug("Server requested full state report") + payload = self._client.build_full_state_message() + self.send(payload) + + msg_data = MessageData.from_server_message(message) + _safe_invoke( + self._callbacks.on_message, + self, + self._client, + msg_data, + ) + def stop(self, timeout: float | None = None) -> None: """ Signal server we are disconnecting and then threads to exit diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/callbacks.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/callbacks.py new file mode 100644 index 00000000000..78bffca66ba --- /dev/null +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/callbacks.py @@ -0,0 +1,94 @@ +# 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 __future__ import annotations + +from abc import ABC +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from opentelemetry._opamp.proto import opamp_pb2 + +if TYPE_CHECKING: + from opentelemetry._opamp.agent import OpAMPAgent + from opentelemetry._opamp.client import OpAMPClient + + +@dataclass +class MessageData: + """Structured view of a ServerToAgent message for callback consumption. + + Only fields the agent is expected to act on are exposed. Flags and + error_response are handled internally by the client before this + object reaches the callback. + """ + + remote_config: opamp_pb2.AgentRemoteConfig | None = None + + @classmethod + def from_server_message( + cls, message: opamp_pb2.ServerToAgent + ) -> MessageData: + return cls( + remote_config=message.remote_config + if message.HasField("remote_config") + else None, + ) + + +class Callbacks(ABC): + """OpAMP client callbacks with no-op defaults. + + All methods have no-op defaults so that subclasses only need to + override the callbacks they care about. New callbacks can be added + in the future without breaking existing subclasses. + """ + + def on_connect(self, agent: OpAMPAgent, client: OpAMPClient) -> None: + """Called when the connection is successfully established to the + Server. For HTTP clients this is called for any request if the + response status is OK. + """ + + def on_connect_failed( + self, + agent: OpAMPAgent, + client: OpAMPClient, + error: Exception, + ) -> None: + """Called when the connection to the Server cannot be established. + May also be called if the connection is lost and reconnection + attempt fails. + """ + + def on_error( + self, + agent: OpAMPAgent, + client: OpAMPClient, + error_response: opamp_pb2.ServerErrorResponse, + ) -> None: + """Called when the Server reports an error in response to a + previously sent request. Useful for logging purposes. The Agent + should not attempt to process the error by reconnecting or + retrying previous operations. The client handles the UNAVAILABLE + case internally by performing retries as necessary. + """ + + def on_message( + self, + agent: OpAMPAgent, + client: OpAMPClient, + message: MessageData, + ) -> None: + """Called when the Agent receives a message that needs processing.""" diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/requests.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/requests.py index 974da6906b3..6c29a22d23e 100644 --- a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/requests.py +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/transport/requests.py @@ -59,8 +59,7 @@ def send( ) response.raise_for_status() except Exception as exc: - logger.error(str(exc)) - raise OpAMPException + raise OpAMPException(str(exc)) from exc message = messages.decode_message(response.content) diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/cassettes/test_connection_remote_config_status_heartbeat_disconnection.yaml b/opamp/opentelemetry-opamp-client/tests/opamp/cassettes/test_connection_remote_config_status_heartbeat_disconnection.yaml index 74db5d2d221..df254d37145 100644 --- a/opamp/opentelemetry-opamp-client/tests/opamp/cassettes/test_connection_remote_config_status_heartbeat_disconnection.yaml +++ b/opamp/opentelemetry-opamp-client/tests/opamp/cassettes/test_connection_remote_config_status_heartbeat_disconnection.yaml @@ -56,10 +56,10 @@ interactions: body: string: !!binary | ChABnL5b5k5046/FazbAJ7r4GioKBgoECgASABIg47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZ - G3hSuFUwAVIA + G3hSuFVSAA== headers: Content-Length: - - '66' + - '64' Content-Type: - application/x-protobuf Date: @@ -89,10 +89,10 @@ interactions: body: string: !!binary | ChABnL5b5k5046/FazbAJ7r4GioKBgoECgASABIg47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZ - G3hSuFUwAVIA + G3hSuFVSAA== headers: Content-Length: - - '66' + - '64' Content-Type: - application/x-protobuf Date: @@ -122,10 +122,10 @@ interactions: body: string: !!binary | ChABnL5b5k5046/FazbAJ7r4GioKBgoECgASABIg47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZ - G3hSuFUwAVIA + G3hSuFVSAA== headers: Content-Length: - - '66' + - '64' Content-Type: - application/x-protobuf Date: diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py index 95821511767..9c7e7f34f01 100644 --- a/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py @@ -16,20 +16,26 @@ from time import sleep from unittest import mock -from opentelemetry._opamp.agent import OpAMPAgent +from opentelemetry._opamp.agent import OpAMPAgent, _safe_invoke from opentelemetry._opamp.agent import _Job as Job +from opentelemetry._opamp.callbacks import Callbacks, MessageData +from opentelemetry._opamp.proto import opamp_pb2 + + +class _NoOpCallbacks(Callbacks): + pass def test_can_instantiate_agent(): agent = OpAMPAgent( - interval=30, client=mock.Mock(), message_handler=mock.Mock() + interval=30, client=mock.Mock(), callbacks=_NoOpCallbacks() ) assert isinstance(agent, OpAMPAgent) def test_can_start_agent(): agent = OpAMPAgent( - interval=30, client=mock.Mock(), message_handler=mock.Mock() + interval=30, client=mock.Mock(), callbacks=_NoOpCallbacks() ) agent.start() agent.stop() @@ -37,12 +43,13 @@ def test_can_start_agent(): def test_agent_start_will_send_connection_and_disconnetion_messages(): client_mock = mock.Mock() - mock_message = {"mock": "message"} + mock_message = mock.Mock() + mock_message.HasField.return_value = False + mock_message.flags = 0 client_mock.send.return_value = mock_message - message_handler = mock.Mock() - agent = OpAMPAgent( - interval=30, client=client_mock, message_handler=message_handler - ) + + cb = mock.create_autospec(Callbacks, instance=True) + agent = OpAMPAgent(interval=30, client=client_mock, callbacks=cb) agent.start() # wait for the queue to be consumed sleep(0.1) @@ -52,13 +59,16 @@ def test_agent_start_will_send_connection_and_disconnetion_messages(): assert client_mock.send.call_count == 2 # connection callback has been called assert agent._schedule is True - # connection message response has been received - message_handler.assert_called_once_with(agent, client_mock, mock_message) + # on_connect and on_message called for the connection response + cb.on_connect.assert_called_once_with(agent, client_mock) + cb.on_message.assert_called_once_with( + agent, client_mock, MessageData(remote_config=None) + ) def test_agent_can_call_agent_stop_multiple_times(): agent = OpAMPAgent( - interval=30, client=mock.Mock(), message_handler=mock.Mock() + interval=30, client=mock.Mock(), callbacks=_NoOpCallbacks() ) agent.start() agent.stop() @@ -67,14 +77,14 @@ def test_agent_can_call_agent_stop_multiple_times(): def test_agent_can_call_agent_stop_before_start(): agent = OpAMPAgent( - interval=30, client=mock.Mock(), message_handler=mock.Mock() + interval=30, client=mock.Mock(), callbacks=_NoOpCallbacks() ) agent.stop() def test_agent_send_warns_without_worker_thread(caplog): agent = OpAMPAgent( - interval=30, client=mock.Mock(), message_handler=mock.Mock() + interval=30, client=mock.Mock(), callbacks=_NoOpCallbacks() ) agent.send(payload="payload") @@ -89,19 +99,26 @@ def test_agent_send_warns_without_worker_thread(caplog): def test_agent_retries_before_max_attempts(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") - message_handler_mock = mock.Mock() + + cb = mock.create_autospec(Callbacks, instance=True) client_mock = mock.Mock() - connection_message = disconnection_message = server_message = mock.Mock() + connection_message = mock.Mock() + connection_message.HasField.return_value = False + connection_message.flags = 0 + server_message = mock.Mock() + server_message.HasField.return_value = False + server_message.flags = 0 + disconnection_message = mock.Mock() client_mock.send.side_effect = [ connection_message, - Exception, + Exception("fail"), server_message, disconnection_message, ] agent = OpAMPAgent( interval=30, client=client_mock, - message_handler=message_handler_mock, + callbacks=cb, initial_backoff=0, ) agent.start() @@ -111,24 +128,32 @@ def test_agent_retries_before_max_attempts(caplog): agent.stop() assert client_mock.send.call_count == 4 - assert message_handler_mock.call_count == 2 + assert cb.on_message.call_count == 2 + assert cb.on_connect.call_count == 2 + assert cb.on_connect_failed.call_count == 1 def test_agent_stops_after_max_attempts(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") - message_handler_mock = mock.Mock() + + cb = mock.create_autospec(Callbacks, instance=True) client_mock = mock.Mock() - connection_message = disconnection_message = mock.Mock() + connection_message = mock.Mock() + connection_message.HasField.return_value = False + connection_message.flags = 0 + disconnection_message = mock.Mock() + exc1 = Exception("fail1") + exc2 = Exception("fail2") client_mock.send.side_effect = [ connection_message, - Exception, - Exception, + exc1, + exc2, disconnection_message, ] agent = OpAMPAgent( interval=30, client=client_mock, - message_handler=message_handler_mock, + callbacks=cb, max_retries=1, initial_backoff=0, ) @@ -139,26 +164,199 @@ def test_agent_stops_after_max_attempts(caplog): agent.stop() assert client_mock.send.call_count == 4 - assert message_handler_mock.call_count == 1 + assert cb.on_message.call_count == 1 + assert cb.on_connect_failed.call_count == 2 + cb.on_connect_failed.assert_any_call(agent, client_mock, exc1) + cb.on_connect_failed.assert_any_call(agent, client_mock, exc2) def test_agent_send_enqueues_job(): - message_handler_mock = mock.Mock() - agent = OpAMPAgent( - interval=30, client=mock.Mock(), message_handler=message_handler_mock - ) + cb = mock.create_autospec(Callbacks, instance=True) + client_mock = mock.Mock() + msg = mock.Mock() + msg.HasField.return_value = False + msg.flags = 0 + client_mock.send.return_value = msg + + agent = OpAMPAgent(interval=30, client=client_mock, callbacks=cb) agent.start() # wait for the queue to be consumed sleep(0.1) - # message handler called for connection message - assert message_handler_mock.call_count == 1 + # on_message called for connection message + assert cb.on_message.call_count == 1 agent.send(payload="payload") # wait for the queue to be consumed sleep(0.1) agent.stop() - # message handler called once for connection and once for our message - assert message_handler_mock.call_count == 2 + # on_message called once for connection and once for our message + assert cb.on_message.call_count == 2 + + +def test_on_error_called_without_on_message_for_error_response(): + cb = mock.create_autospec(Callbacks, instance=True) + client_mock = mock.Mock() + + error_response = opamp_pb2.ServerErrorResponse( + error_message="server error", + ) + server_msg = opamp_pb2.ServerToAgent( + error_response=error_response, + ) + # connection message (no error) + conn_msg = opamp_pb2.ServerToAgent() + + client_mock.send.side_effect = [ + conn_msg, # connection + server_msg, # message with error_response + mock.Mock(), # disconnect + ] + agent = OpAMPAgent(interval=30, client=client_mock, callbacks=cb) + agent.start() + agent.send(payload="payload") + sleep(0.1) + agent.stop() + + # on_message called only for connection (not for error_response message) + assert cb.on_message.call_count == 1 + # on_error called for the message with error_response + cb.on_error.assert_called_once_with(agent, client_mock, error_response) + + +def test_on_error_not_called_without_error_response(): + cb = mock.create_autospec(Callbacks, instance=True) + client_mock = mock.Mock() + + server_msg = opamp_pb2.ServerToAgent() + client_mock.send.side_effect = [ + server_msg, # connection + server_msg, # message without error_response + mock.Mock(), # disconnect + ] + agent = OpAMPAgent(interval=30, client=client_mock, callbacks=cb) + agent.start() + agent.send(payload="payload") + sleep(0.1) + agent.stop() + + assert cb.on_message.call_count == 2 + cb.on_error.assert_not_called() + + +def test_dispatch_order_with_error(): + """Verify that error_response skips on_message: on_connect -> on_error.""" + call_order = [] + client_mock = mock.Mock() + + error_response = opamp_pb2.ServerErrorResponse( + error_message="err", + ) + server_msg = opamp_pb2.ServerToAgent( + error_response=error_response, + ) + + class OrderTrackingCallbacks(Callbacks): + def on_connect(self, agent, client): + call_order.append("on_connect") + + def on_message(self, agent, client, message): + call_order.append("on_message") + + def on_error(self, agent, client, error_response): + call_order.append("on_error") + + client_mock.send.side_effect = [ + server_msg, # connection message with error + mock.Mock(), # disconnect + ] + agent = OpAMPAgent( + interval=30, client=client_mock, callbacks=OrderTrackingCallbacks() + ) + agent.start() + sleep(0.1) + agent.stop() + + assert call_order == ["on_connect", "on_error"] + + +def test_dispatch_order_without_error(): + """Verify normal dispatch order: on_connect -> on_message.""" + call_order = [] + client_mock = mock.Mock() + + server_msg = opamp_pb2.ServerToAgent() + + class OrderTrackingCallbacks(Callbacks): + def on_connect(self, agent, client): + call_order.append("on_connect") + + def on_message(self, agent, client, message): + call_order.append("on_message") + + def on_error(self, agent, client, error_response): + call_order.append("on_error") + + client_mock.send.side_effect = [ + server_msg, # connection message, no error + mock.Mock(), # disconnect + ] + agent = OpAMPAgent( + interval=30, client=client_mock, callbacks=OrderTrackingCallbacks() + ) + agent.start() + sleep(0.1) + agent.stop() + + assert call_order == ["on_connect", "on_message"] + + +def test_report_full_state_flag_triggers_full_state_send(): + cb = mock.create_autospec(Callbacks, instance=True) + client_mock = mock.Mock() + + conn_msg = opamp_pb2.ServerToAgent() + flag_msg = opamp_pb2.ServerToAgent( + flags=opamp_pb2.ServerToAgentFlags_ReportFullState, + ) + + no_flag_msg = opamp_pb2.ServerToAgent() + client_mock.send.side_effect = [ + conn_msg, # connection + flag_msg, # response with ReportFullState + no_flag_msg, # full state response + no_flag_msg, # disconnect + ] + client_mock.build_full_state_message.return_value = b"full-state" + + agent = OpAMPAgent(interval=30, client=client_mock, callbacks=cb) + agent.start() + agent.send(payload="payload") + sleep(0.2) + agent.stop() + + client_mock.build_full_state_message.assert_called() + + +def test_safe_invoke_logs_error(caplog): + caplog.set_level(logging.ERROR, logger="opentelemetry._opamp.agent") + + def bad_callback(): + raise ValueError("boom") + + _safe_invoke(bad_callback) + + assert any( + "Error when invoking function 'bad_callback'" in record.message + for record in caplog.records + ) + + +def test_safe_invoke_does_not_propagate(): + def bad_callback(): + raise RuntimeError("should not propagate") + + # Should not raise + _safe_invoke(bad_callback) def test_can_instantiate_job(): diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_callbacks.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_callbacks.py new file mode 100644 index 00000000000..66ec8ef0852 --- /dev/null +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_callbacks.py @@ -0,0 +1,36 @@ +# 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 unittest import mock + +from opentelemetry._opamp.callbacks import Callbacks, MessageData +from opentelemetry._opamp.proto import opamp_pb2 + + +def test_subclass_override_subset(): + class MyCallbacks(Callbacks): + def __init__(self): + self.connected = False + + def on_connect(self, agent, client): + self.connected = True + + cb = MyCallbacks() + cb.on_connect(mock.Mock(), mock.Mock()) + assert cb.connected is True + + # non-overridden methods still work as no-ops + cb.on_connect_failed(mock.Mock(), mock.Mock(), Exception()) + cb.on_message(mock.Mock(), mock.Mock(), MessageData()) + cb.on_error(mock.Mock(), mock.Mock(), opamp_pb2.ServerErrorResponse()) diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py index 68ceec414b9..56998dd255c 100644 --- a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py @@ -20,6 +20,7 @@ import pytest from opentelemetry._opamp.agent import OpAMPAgent +from opentelemetry._opamp.callbacks import Callbacks from opentelemetry._opamp.client import OpAMPClient from opentelemetry._opamp.proto import opamp_pb2 @@ -32,26 +33,32 @@ def test_connection_remote_config_status_heartbeat_disconnection(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") - def opamp_handler(agent, client, message): - logger = logging.getLogger("opentelemetry._opamp.agent.opamp_handler") + class E2ECallbacks(Callbacks): + def on_message(self, agent, client, message): + logger = logging.getLogger( + "opentelemetry._opamp.agent.opamp_handler" + ) - logger.debug("In opamp_handler") + logger.debug("In opamp_handler") - # we need to update the config only if we have a config - if not message.remote_config.config_hash: - return + # we need to update the config only if we have a config + if ( + message.remote_config is None + or not message.remote_config.config_hash + ): + return - updated_remote_config = client.update_remote_config_status( - remote_config_hash=message.remote_config.config_hash, - status=opamp_pb2.RemoteConfigStatuses_APPLIED, - error_message="", - ) - if updated_remote_config is not None: - logger.debug("Updated Remote Config") - message = client.build_remote_config_status_response_message( - updated_remote_config + updated_remote_config = client.update_remote_config_status( + remote_config_hash=message.remote_config.config_hash, + status=opamp_pb2.RemoteConfigStatuses_APPLIED, + error_message="", ) - agent.send(payload=message) + if updated_remote_config is not None: + logger.debug("Updated Remote Config") + msg = client.build_remote_config_status_response_message( + updated_remote_config + ) + agent.send(payload=msg) opamp_client = OpAMPClient( endpoint="https://localhost:4320/v1/opamp", @@ -63,7 +70,7 @@ def opamp_handler(agent, client, message): ) opamp_agent = OpAMPAgent( interval=1, - message_handler=opamp_handler, + callbacks=E2ECallbacks(), client=opamp_client, ) opamp_agent.start() @@ -78,12 +85,14 @@ def opamp_handler(agent, client, message): for record in caplog.record_tuples if record[0] == "opentelemetry._opamp.agent.opamp_handler" ] - # one call is for connection, one is remote config status, one is heartbeat + # connection response has ReportFullState flag, triggering a full state send. + # on_message is called for: connection, full state response, config status response, heartbeat. assert handler_records == [ "In opamp_handler", "Updated Remote Config", "In opamp_handler", "In opamp_handler", + "In opamp_handler", ] @@ -95,7 +104,7 @@ def opamp_handler(agent, client, message): def test_with_server_not_responding(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") - opamp_handler = mock.Mock() + cb = mock.create_autospec(Callbacks, instance=True) opamp_client = OpAMPClient( endpoint="https://localhost:4399/v1/opamp", @@ -107,11 +116,11 @@ def test_with_server_not_responding(caplog): ) opamp_agent = OpAMPAgent( interval=1, - message_handler=opamp_handler, + callbacks=cb, client=opamp_client, ) opamp_agent.start() opamp_agent.stop() - assert opamp_handler.call_count == 0 + assert cb.on_message.call_count == 0 From 242cfe1c58d6896144d75c404a4784d4bd16cfed Mon Sep 17 00:00:00 2001 From: "otelbot[bot]" <197425009+otelbot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:29:10 +0000 Subject: [PATCH 32/78] Update opentelemetry-opamp-client version to v0.2b0 (#4352) Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com> --- opamp/opentelemetry-opamp-client/CHANGELOG.md | 2 ++ .../src/opentelemetry/_opamp/version.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/opamp/opentelemetry-opamp-client/CHANGELOG.md b/opamp/opentelemetry-opamp-client/CHANGELOG.md index f981e2dcf39..9b8f2289899 100644 --- a/opamp/opentelemetry-opamp-client/CHANGELOG.md +++ b/opamp/opentelemetry-opamp-client/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 0.1b0 (2026-03-23) + - Initial implementation ([#3635](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3635)) - Update client to have additional callback methods diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py index e7bf4a48eb5..29e61950cc7 100644 --- a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.1b0.dev" +__version__ = "0.2b0.dev" From 56e1f3917d3921ed225177842b38d5f33d7ef9a3 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 24 Mar 2026 15:58:21 +0100 Subject: [PATCH 33/78] opamp/opentelemetry-opamp-client: add python 3.14 to classifiers (#4354) --- opamp/opentelemetry-opamp-client/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/opamp/opentelemetry-opamp-client/pyproject.toml b/opamp/opentelemetry-opamp-client/pyproject.toml index 31f10501c5e..978878c6207 100644 --- a/opamp/opentelemetry-opamp-client/pyproject.toml +++ b/opamp/opentelemetry-opamp-client/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] dependencies = [ "opentelemetry-api ~= 1.12", From 7747dcaf5de91000ec3eca96f5be155f14fef629 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 24 Mar 2026 16:07:34 +0100 Subject: [PATCH 34/78] opentelemetry-opamp-client: rename Callbacks to OpAMPCallbacks (#4355) --- opamp/opentelemetry-opamp-client/CHANGELOG.md | 3 +++ .../src/opentelemetry/_opamp/__init__.py | 10 ++++----- .../src/opentelemetry/_opamp/agent.py | 6 ++--- .../src/opentelemetry/_opamp/callbacks.py | 2 +- .../tests/opamp/test_agent.py | 22 +++++++++---------- .../tests/opamp/test_callbacks.py | 4 ++-- .../tests/opamp/test_e2e.py | 6 ++--- 7 files changed, 28 insertions(+), 25 deletions(-) diff --git a/opamp/opentelemetry-opamp-client/CHANGELOG.md b/opamp/opentelemetry-opamp-client/CHANGELOG.md index 9b8f2289899..60e9f9ebcda 100644 --- a/opamp/opentelemetry-opamp-client/CHANGELOG.md +++ b/opamp/opentelemetry-opamp-client/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Breaking change: callback class `Callbacks` renamed to `OpAMPCallbacks` + ([#4355](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4355)) + ## Version 0.1b0 (2026-03-23) - Initial implementation diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py index ed85131f047..0a9cefcd1fb 100644 --- a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/__init__.py @@ -35,7 +35,7 @@ Since OpAMP APIs, config options or environment variables are not standardizes the distros are required to provide code doing so. -OTel Python distros would need to provide their own Callbacks subclass that implements the actual +OTel Python distros would need to provide their own OpAMPCallbacks subclass that implements the actual change of whatever configuration their backends sends. Please note that the API is not finalized yet and so the name is called ``_opamp`` with the underscore. @@ -48,13 +48,13 @@ import os from opentelemetry._opamp.agent import OpAMPAgent - from opentelemetry._opamp.callbacks import Callbacks + from opentelemetry._opamp.callbacks import OpAMPCallbacks from opentelemetry._opamp.client import OpAMPClient from opentelemetry.sdk._configuration import _OTelSDKConfigurator from opentelemetry.sdk.resources import OTELResourceDetector - class MyCallbacks(Callbacks): + class MyCallbacks(OpAMPCallbacks): def on_message(self, agent, client, message): if message.remote_config is None: return @@ -93,7 +93,7 @@ def _configure(self, **kwargs): """ from opentelemetry._opamp.agent import OpAMPAgent -from opentelemetry._opamp.callbacks import Callbacks, MessageData +from opentelemetry._opamp.callbacks import MessageData, OpAMPCallbacks from opentelemetry._opamp.client import OpAMPClient -__all__ = ["Callbacks", "MessageData", "OpAMPAgent", "OpAMPClient"] +__all__ = ["MessageData", "OpAMPAgent", "OpAMPCallbacks", "OpAMPClient"] diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py index 2616726fcce..917f753a4fa 100644 --- a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/agent.py @@ -21,7 +21,7 @@ import threading from typing import Any, Callable -from opentelemetry._opamp.callbacks import Callbacks, MessageData +from opentelemetry._opamp.callbacks import MessageData, OpAMPCallbacks from opentelemetry._opamp.client import OpAMPClient from opentelemetry._opamp.proto import opamp_pb2 @@ -85,7 +85,7 @@ def __init__( self, *, interval: float = 30, - callbacks: Callbacks, + callbacks: OpAMPCallbacks, max_retries: int = 10, heartbeat_max_retries: int = 1, initial_backoff: float = 1.0, @@ -93,7 +93,7 @@ def __init__( ): """ :param interval: seconds between heartbeat calls - :param callbacks: Callbacks instance for receiving client events + :param callbacks: OpAMPCallbacks instance for receiving client events :param max_retries: how many times to retry a failed job for ad-hoc messages :param heartbeat_max_retries: how many times to retry an heartbeat failed job :param initial_backoff: base seconds for exponential backoff diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/callbacks.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/callbacks.py index 78bffca66ba..c543793ded2 100644 --- a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/callbacks.py +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/callbacks.py @@ -47,7 +47,7 @@ def from_server_message( ) -class Callbacks(ABC): +class OpAMPCallbacks(ABC): """OpAMP client callbacks with no-op defaults. All methods have no-op defaults so that subclasses only need to diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py index 9c7e7f34f01..e66598df737 100644 --- a/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_agent.py @@ -18,11 +18,11 @@ from opentelemetry._opamp.agent import OpAMPAgent, _safe_invoke from opentelemetry._opamp.agent import _Job as Job -from opentelemetry._opamp.callbacks import Callbacks, MessageData +from opentelemetry._opamp.callbacks import MessageData, OpAMPCallbacks from opentelemetry._opamp.proto import opamp_pb2 -class _NoOpCallbacks(Callbacks): +class _NoOpCallbacks(OpAMPCallbacks): pass @@ -48,7 +48,7 @@ def test_agent_start_will_send_connection_and_disconnetion_messages(): mock_message.flags = 0 client_mock.send.return_value = mock_message - cb = mock.create_autospec(Callbacks, instance=True) + cb = mock.create_autospec(OpAMPCallbacks, instance=True) agent = OpAMPAgent(interval=30, client=client_mock, callbacks=cb) agent.start() # wait for the queue to be consumed @@ -100,7 +100,7 @@ def test_agent_send_warns_without_worker_thread(caplog): def test_agent_retries_before_max_attempts(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") - cb = mock.create_autospec(Callbacks, instance=True) + cb = mock.create_autospec(OpAMPCallbacks, instance=True) client_mock = mock.Mock() connection_message = mock.Mock() connection_message.HasField.return_value = False @@ -136,7 +136,7 @@ def test_agent_retries_before_max_attempts(caplog): def test_agent_stops_after_max_attempts(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") - cb = mock.create_autospec(Callbacks, instance=True) + cb = mock.create_autospec(OpAMPCallbacks, instance=True) client_mock = mock.Mock() connection_message = mock.Mock() connection_message.HasField.return_value = False @@ -171,7 +171,7 @@ def test_agent_stops_after_max_attempts(caplog): def test_agent_send_enqueues_job(): - cb = mock.create_autospec(Callbacks, instance=True) + cb = mock.create_autospec(OpAMPCallbacks, instance=True) client_mock = mock.Mock() msg = mock.Mock() msg.HasField.return_value = False @@ -194,7 +194,7 @@ def test_agent_send_enqueues_job(): def test_on_error_called_without_on_message_for_error_response(): - cb = mock.create_autospec(Callbacks, instance=True) + cb = mock.create_autospec(OpAMPCallbacks, instance=True) client_mock = mock.Mock() error_response = opamp_pb2.ServerErrorResponse( @@ -224,7 +224,7 @@ def test_on_error_called_without_on_message_for_error_response(): def test_on_error_not_called_without_error_response(): - cb = mock.create_autospec(Callbacks, instance=True) + cb = mock.create_autospec(OpAMPCallbacks, instance=True) client_mock = mock.Mock() server_msg = opamp_pb2.ServerToAgent() @@ -255,7 +255,7 @@ def test_dispatch_order_with_error(): error_response=error_response, ) - class OrderTrackingCallbacks(Callbacks): + class OrderTrackingCallbacks(OpAMPCallbacks): def on_connect(self, agent, client): call_order.append("on_connect") @@ -286,7 +286,7 @@ def test_dispatch_order_without_error(): server_msg = opamp_pb2.ServerToAgent() - class OrderTrackingCallbacks(Callbacks): + class OrderTrackingCallbacks(OpAMPCallbacks): def on_connect(self, agent, client): call_order.append("on_connect") @@ -311,7 +311,7 @@ def on_error(self, agent, client, error_response): def test_report_full_state_flag_triggers_full_state_send(): - cb = mock.create_autospec(Callbacks, instance=True) + cb = mock.create_autospec(OpAMPCallbacks, instance=True) client_mock = mock.Mock() conn_msg = opamp_pb2.ServerToAgent() diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_callbacks.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_callbacks.py index 66ec8ef0852..9493155af0b 100644 --- a/opamp/opentelemetry-opamp-client/tests/opamp/test_callbacks.py +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_callbacks.py @@ -14,12 +14,12 @@ from unittest import mock -from opentelemetry._opamp.callbacks import Callbacks, MessageData +from opentelemetry._opamp.callbacks import MessageData, OpAMPCallbacks from opentelemetry._opamp.proto import opamp_pb2 def test_subclass_override_subset(): - class MyCallbacks(Callbacks): + class MyCallbacks(OpAMPCallbacks): def __init__(self): self.connected = False diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py index 56998dd255c..1bb9df6a4cc 100644 --- a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py @@ -20,7 +20,7 @@ import pytest from opentelemetry._opamp.agent import OpAMPAgent -from opentelemetry._opamp.callbacks import Callbacks +from opentelemetry._opamp.callbacks import OpAMPCallbacks from opentelemetry._opamp.client import OpAMPClient from opentelemetry._opamp.proto import opamp_pb2 @@ -33,7 +33,7 @@ def test_connection_remote_config_status_heartbeat_disconnection(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") - class E2ECallbacks(Callbacks): + class E2ECallbacks(OpAMPCallbacks): def on_message(self, agent, client, message): logger = logging.getLogger( "opentelemetry._opamp.agent.opamp_handler" @@ -104,7 +104,7 @@ def on_message(self, agent, client, message): def test_with_server_not_responding(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") - cb = mock.create_autospec(Callbacks, instance=True) + cb = mock.create_autospec(OpAMPCallbacks, instance=True) opamp_client = OpAMPClient( endpoint="https://localhost:4399/v1/opamp", From a983382ce2fd92fe57fc60edbd761a100e54d958 Mon Sep 17 00:00:00 2001 From: Rohan Sood <56945243+rohansood10@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:16:37 -0700 Subject: [PATCH 35/78] Fix dead benchmarks link in documentation (#4238) --- docs/performance/benchmarks.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/performance/benchmarks.rst b/docs/performance/benchmarks.rst index 99859a27d80..9ef78c099df 100644 --- a/docs/performance/benchmarks.rst +++ b/docs/performance/benchmarks.rst @@ -1,4 +1,8 @@ Performance Tests - Benchmarks ============================== -Click `here `_ to view the latest performance benchmarks for packages in this repo. +For instructions on running and writing benchmarks locally, see the +`Benchmarks section of CONTRIBUTING.md `_. + +Live benchmark results are published at +`opentelemetry.io/docs/languages/python/benchmarks `_. From 70f2b8c73da8879ba9b355ebf060b58815748d4f Mon Sep 17 00:00:00 2001 From: Nicolas Sterchele Date: Wed, 25 Mar 2026 12:12:53 +0100 Subject: [PATCH 36/78] fix(confluent-kafka): skip recv spans when poll/consume returns no messages (#4349) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Matches Java instrumentation behavior: only create a recv span when a message is actually received, avoiding empty spans on idle polls. Fixes #3590 Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- CHANGELOG.md | 2 + .../confluent_kafka/__init__.py | 33 ++++---- .../tests/test_instrumentation.py | 82 ++++++++++++++++++- 3 files changed, 96 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 564340ae262..3c9c67be4bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-docker-tests`: Replace deprecated `SpanAttributes` from `opentelemetry.semconv.trace` with `opentelemetry.semconv._incubating.attributes` ([#4339](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4339)) +- `opentelemetry-instrumentation-confluent-kafka`: Skip `recv` span creation when `poll()` returns no message or `consume()` returns an empty list, avoiding empty spans on idle polls + ([#4349](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4349)) - Fix intermittent `Core Contrib Test` CI failures caused by GitHub git CDN SHA propagation lag by installing core packages from the already-checked-out local copy instead of a second git clone ([#4305](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4305)) - Don't import module in unwrap if not already imported diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py index f4606bc4d90..ed390d7006a 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/__init__.py @@ -383,11 +383,11 @@ def wrap_poll(func, instance, tracer, args, kwargs): if instance._current_consume_span: _end_current_consume_span(instance) - with tracer.start_as_current_span( - "recv", end_on_exit=True, kind=trace.SpanKind.CONSUMER - ): - record = func(*args, **kwargs) - if record: + record = func(*args, **kwargs) + if record: + with tracer.start_as_current_span( + "recv", end_on_exit=True, kind=trace.SpanKind.CONSUMER + ): _create_new_consume_span(instance, tracer, [record]) _enrich_span( instance._current_consume_span, @@ -396,9 +396,9 @@ def wrap_poll(func, instance, tracer, args, kwargs): record.offset(), operation=MessagingOperationTypeValues.PROCESS, ) - instance._current_context_token = context.attach( - trace.set_span_in_context(instance._current_consume_span) - ) + instance._current_context_token = context.attach( + trace.set_span_in_context(instance._current_consume_span) + ) return record @@ -407,21 +407,20 @@ def wrap_consume(func, instance, tracer, args, kwargs): if instance._current_consume_span: _end_current_consume_span(instance) - with tracer.start_as_current_span( - "recv", end_on_exit=True, kind=trace.SpanKind.CONSUMER - ): - records = func(*args, **kwargs) - if len(records) > 0: + records = func(*args, **kwargs) + if len(records) > 0: + with tracer.start_as_current_span( + "recv", end_on_exit=True, kind=trace.SpanKind.CONSUMER + ): _create_new_consume_span(instance, tracer, records) _enrich_span( instance._current_consume_span, records[0].topic(), operation=MessagingOperationTypeValues.PROCESS, ) - - instance._current_context_token = context.attach( - trace.set_span_in_context(instance._current_consume_span) - ) + instance._current_context_token = context.attach( + trace.set_span_in_context(instance._current_consume_span) + ) return records diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py index 365ac333d9c..772ecd09ee6 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/tests/test_instrumentation.py @@ -197,7 +197,6 @@ def test_poll(self) -> None: MESSAGING_MESSAGE_ID: "topic-30.1.3", }, }, - {"name": "recv", "attributes": {}}, ] consumer = MockConsumer( @@ -213,7 +212,7 @@ def test_poll(self) -> None: consumer.poll() consumer.poll() consumer.poll() - consumer.poll() + consumer.poll() # empty poll — must not produce a span span_list = self.memory_exporter.get_finished_spans() self._compare_spans(span_list, expected_spans) @@ -259,7 +258,6 @@ def test_consume(self) -> None: SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value, }, }, - {"name": "recv", "attributes": {}}, ] consumer = MockConsumer( @@ -276,10 +274,86 @@ def test_consume(self) -> None: consumer.consume(3) consumer.consume(1) consumer.consume(2) - consumer.consume(1) + consumer.consume(1) # empty consume — must not produce a span span_list = self.memory_exporter.get_finished_spans() self._compare_spans(span_list, expected_spans) + def test_poll_empty_does_not_create_span(self) -> None: + instrumentation = ConfluentKafkaInstrumentor() + consumer = MockConsumer( + [], + { + "bootstrap.servers": "localhost:29092", + "group.id": "mygroup", + "auto.offset.reset": "earliest", + }, + ) + self.memory_exporter.clear() + consumer = instrumentation.instrument_consumer(consumer) + consumer.poll() + consumer.poll() + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 0) + + def test_consume_empty_does_not_create_span(self) -> None: + instrumentation = ConfluentKafkaInstrumentor() + consumer = MockConsumer( + [], + { + "bootstrap.servers": "localhost:29092", + "group.id": "mygroup", + "auto.offset.reset": "earliest", + }, + ) + self.memory_exporter.clear() + consumer = instrumentation.instrument_consumer(consumer) + consumer.consume(5) + consumer.consume(5) + + span_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(span_list), 0) + + def test_poll_empty_cleans_up_previous_span_and_token(self) -> None: + instrumentation = ConfluentKafkaInstrumentor() + consumer = MockConsumer( + [MockedMessage("topic-1", 0, 0, [])], + { + "bootstrap.servers": "localhost:29092", + "group.id": "mygroup", + "auto.offset.reset": "earliest", + }, + ) + consumer = instrumentation.instrument_consumer(consumer) + consumer.poll() # non-empty: sets _current_consume_span and _current_context_token + self.assertIsNotNone(consumer._current_consume_span) + self.assertIsNotNone(consumer._current_context_token) + + consumer.poll() # empty: should clean up both + self.assertIsNone(consumer._current_consume_span) + self.assertIsNone(consumer._current_context_token) + + def test_consume_empty_cleans_up_previous_span_and_token(self) -> None: + instrumentation = ConfluentKafkaInstrumentor() + consumer = MockConsumer( + [MockedMessage("topic-1", 0, 0, [])], + { + "bootstrap.servers": "localhost:29092", + "group.id": "mygroup", + "auto.offset.reset": "earliest", + }, + ) + consumer = instrumentation.instrument_consumer(consumer) + consumer.consume( + 1 + ) # non-empty: sets _current_consume_span and _current_context_token + self.assertIsNotNone(consumer._current_consume_span) + self.assertIsNotNone(consumer._current_context_token) + + consumer.consume(1) # empty: should clean up both + self.assertIsNone(consumer._current_consume_span) + self.assertIsNone(consumer._current_context_token) + def test_close(self) -> None: instrumentation = ConfluentKafkaInstrumentor() mocked_messages = [ From 822cd77b25444f874a1eb289529d0234fe794034 Mon Sep 17 00:00:00 2001 From: Surya Date: Wed, 25 Mar 2026 07:18:08 -0400 Subject: [PATCH 37/78] fix(genai-openai): fix for ChoiceBuffer crashes on streaming tool-call deltas with arguments=None. (#4350) * wip: fix for none/null in function tool calls. * polish: add changelog. * wip: fixing lint and precommit. * wip: converted class based tests. * wip: fixing the precommit. --- .../CHANGELOG.md | 2 + .../instrumentation/openai_v2/patch.py | 14 +- .../tests/test_choice_buffer.py | 182 ++++++++++++++++++ 3 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_choice_buffer.py diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index c75cdf2f271..76d2deabc45 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Fix `ChoiceBuffer` crash on streaming tool-call deltas with `arguments=None` + ([#4350](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4350)) - Fix `StreamWrapper` missing `.headers` and other attributes when using `with_raw_response` streaming ([#4113](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/4113)) - Add opt-in support for latest experimental semantic conventions (v1.37.0). Set diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index 3bc42f103ca..2c8c1b4c710 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -582,7 +582,8 @@ def __init__(self, index, tool_call_id, function_name): self.arguments = [] def append_arguments(self, arguments): - self.arguments.append(arguments) + if arguments is not None: + self.arguments.append(arguments) class ChoiceBuffer: @@ -601,13 +602,16 @@ def append_tool_call(self, tool_call): for _ in range(len(self.tool_calls_buffers), idx + 1): self.tool_calls_buffers.append(None) + function = tool_call.function if not self.tool_calls_buffers[idx]: self.tool_calls_buffers[idx] = ToolCallBuffer( - idx, tool_call.id, tool_call.function.name + idx, + tool_call.id, + function.name if function else None, ) - self.tool_calls_buffers[idx].append_arguments( - tool_call.function.arguments - ) + + if function: + self.tool_calls_buffers[idx].append_arguments(function.arguments) class BaseStreamWrapper: diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_choice_buffer.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_choice_buffer.py new file mode 100644 index 00000000000..7717ff73b20 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_choice_buffer.py @@ -0,0 +1,182 @@ +# 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. + +"""Unit tests for ChoiceBuffer and ToolCallBuffer classes.""" + +from openai.types.chat.chat_completion_chunk import ( + ChoiceDeltaToolCall, + ChoiceDeltaToolCallFunction, +) + +from opentelemetry.instrumentation.openai_v2.patch import ( + ChoiceBuffer, + ToolCallBuffer, +) + + +def test_toolcallbuffer_append_arguments_with_string(): + buf = ToolCallBuffer(0, "call_1", "get_weather") + buf.append_arguments('{"city":') + buf.append_arguments(' "NYC"}') + assert "".join(buf.arguments) == '{"city": "NYC"}' + + +def test_toolcallbuffer_append_arguments_with_none_is_skipped(): + """Regression test for issue #4344. + + Some OpenAI-compatible providers (vLLM, TGI, etc.) send + arguments=None on tool-call delta chunks instead of arguments="". + This must not crash when joining the arguments list. + """ + buf = ToolCallBuffer(0, "call_1", "get_weather") + buf.append_arguments(None) + buf.append_arguments('{"city": "NYC"}') + buf.append_arguments(None) + assert "".join(buf.arguments) == '{"city": "NYC"}' + + +def test_toolcallbuffer_append_arguments_all_none(): + buf = ToolCallBuffer(0, "call_1", "get_weather") + buf.append_arguments(None) + buf.append_arguments(None) + assert "".join(buf.arguments) == "" + + +def test_toolcallbuffer_append_arguments_empty_string(): + buf = ToolCallBuffer(0, "call_1", "get_weather") + buf.append_arguments("") + buf.append_arguments('{"city": "NYC"}') + assert "".join(buf.arguments) == '{"city": "NYC"}' + + +def test_choicebuffer_append_tool_call_with_none_arguments(): + """End-to-end regression test for issue #4344. + + Simulates the exact scenario from the bug report where a provider + sends arguments=None on the first tool-call delta chunk. + """ + buf = ChoiceBuffer(0) + buf.append_tool_call( + ChoiceDeltaToolCall( + index=0, + id="call_1", + type="function", + function=ChoiceDeltaToolCallFunction( + name="get_weather", arguments=None + ), + ) + ) + buf.append_tool_call( + ChoiceDeltaToolCall( + index=0, + function=ChoiceDeltaToolCallFunction(arguments='{"city": "NYC"}'), + ) + ) + + # This must not raise TypeError + result = "".join(buf.tool_calls_buffers[0].arguments) + assert result == '{"city": "NYC"}' + + +def test_choicebuffer_append_tool_call_normal_flow(): + """Standard OpenAI flow where arguments="" on first delta.""" + buf = ChoiceBuffer(0) + buf.append_tool_call( + ChoiceDeltaToolCall( + index=0, + id="call_1", + type="function", + function=ChoiceDeltaToolCallFunction( + name="get_weather", arguments="" + ), + ) + ) + buf.append_tool_call( + ChoiceDeltaToolCall( + index=0, + function=ChoiceDeltaToolCallFunction(arguments='{"city": "NYC"}'), + ) + ) + + result = "".join(buf.tool_calls_buffers[0].arguments) + assert result == '{"city": "NYC"}' + + +def test_choicebuffer_append_multiple_tool_calls_with_none_arguments(): + """Multiple tool calls where some have arguments=None.""" + buf = ChoiceBuffer(0) + + # First tool call + buf.append_tool_call( + ChoiceDeltaToolCall( + index=0, + id="call_1", + type="function", + function=ChoiceDeltaToolCallFunction( + name="get_weather", arguments=None + ), + ) + ) + buf.append_tool_call( + ChoiceDeltaToolCall( + index=0, + function=ChoiceDeltaToolCallFunction(arguments='{"city": "NYC"}'), + ) + ) + + # Second tool call + buf.append_tool_call( + ChoiceDeltaToolCall( + index=1, + id="call_2", + type="function", + function=ChoiceDeltaToolCallFunction( + name="get_time", arguments=None + ), + ) + ) + buf.append_tool_call( + ChoiceDeltaToolCall( + index=1, + function=ChoiceDeltaToolCallFunction(arguments='{"tz": "EST"}'), + ) + ) + + assert "".join(buf.tool_calls_buffers[0].arguments) == '{"city": "NYC"}' + assert "".join(buf.tool_calls_buffers[1].arguments) == '{"tz": "EST"}' + + +def test_choicebuffer_append_tool_call_with_none_function(): + """Handle delta chunks where function is None.""" + buf = ChoiceBuffer(0) + buf.append_tool_call( + ChoiceDeltaToolCall( + index=0, + id="call_1", + type="function", + function=ChoiceDeltaToolCallFunction( + name="get_weather", arguments='{"city": "NYC"}' + ), + ) + ) + # Subsequent delta with function=None should not crash + buf.append_tool_call( + ChoiceDeltaToolCall( + index=0, + function=None, + ) + ) + + result = "".join(buf.tool_calls_buffers[0].arguments) + assert result == '{"city": "NYC"}' From 195bcdb7ad46b7fa08b383f9409b9c48e044e759 Mon Sep 17 00:00:00 2001 From: shuningc Date: Thu, 26 Mar 2026 09:32:13 -0700 Subject: [PATCH 38/78] GenAI Utils | Embedding Type and Span Creation (#4219) --- .../pyproject.toml | 17 +- .../tests/requirements.oldest.txt | 6 +- .../pyproject.toml | 16 +- .../tests/requirements.oldest.txt | 6 +- .../pyproject.toml | 15 +- .../tests/requirements.oldest.txt | 6 +- util/opentelemetry-util-genai/CHANGELOG.md | 6 +- util/opentelemetry-util-genai/README.rst | 12 + util/opentelemetry-util-genai/pyproject.toml | 11 +- .../src/opentelemetry/util/genai/handler.py | 151 ++++-- .../opentelemetry/util/genai/span_utils.py | 99 +++- .../src/opentelemetry/util/genai/types.py | 50 +- .../tests/test_utils.py | 439 ++++++------------ .../tests/test_utils_events.py | 380 +++++++++++++++ 14 files changed, 824 insertions(+), 390 deletions(-) create mode 100644 util/opentelemetry-util-genai/tests/test_utils_events.py diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml index 74c411a1a5c..5cc6754ef79 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml @@ -26,16 +26,14 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-api ~= 1.37", - "opentelemetry-instrumentation ~= 0.58b0", - "opentelemetry-semantic-conventions ~= 0.58b0", + "opentelemetry-api ~= 1.39", + "opentelemetry-instrumentation ~= 0.60b0", + "opentelemetry-semantic-conventions ~= 0.60b0", "opentelemetry-util-genai >= 0.2b0, <0.4b0", ] [project.optional-dependencies] -instruments = [ - "anthropic >= 0.51.0", -] +instruments = ["anthropic >= 0.51.0"] [project.entry-points.opentelemetry_instrumentor] anthropic = "opentelemetry.instrumentation.anthropic:AnthropicInstrumentor" @@ -48,15 +46,10 @@ Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" path = "src/opentelemetry/instrumentation/anthropic/version.py" [tool.hatch.build.targets.sdist] -include = [ - "/src", - "/tests", - "/examples", -] +include = ["/src", "/tests", "/examples"] [tool.hatch.build.targets.wheel] packages = ["src/opentelemetry"] [tool.pytest.ini_options] testpaths = ["tests"] - diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/requirements.oldest.txt index 0b77b1a7cb4..1b1d2b19947 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/requirements.oldest.txt @@ -21,8 +21,8 @@ pytest==7.4.4 pytest-vcr==1.0.2 pytest-asyncio==0.21.0 wrapt==1.16.0 -opentelemetry-api==1.37 # when updating, also update in pyproject.toml -opentelemetry-sdk==1.37 # when updating, also update in pyproject.toml -opentelemetry-semantic-conventions==0.58b0 # when updating, also update in pyproject.toml +opentelemetry-api==1.39 # when updating, also update in pyproject.toml +opentelemetry-sdk==1.39 # when updating, also update in pyproject.toml +opentelemetry-semantic-conventions==0.60b0 # when updating, also update in pyproject.toml -e instrumentation-genai/opentelemetry-instrumentation-anthropic diff --git a/instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk/pyproject.toml index 3149629fac0..fb38e615895 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk/pyproject.toml @@ -24,16 +24,14 @@ classifiers = [ "Programming Language :: Python :: 3.13", ] dependencies = [ - "opentelemetry-api ~= 1.37", - "opentelemetry-instrumentation ~= 0.58b0", - "opentelemetry-semantic-conventions ~= 0.58b0", + "opentelemetry-api ~= 1.39", + "opentelemetry-instrumentation ~= 0.60b0", + "opentelemetry-semantic-conventions ~= 0.60b0", "opentelemetry-util-genai >= 0.2b0, <0.4b0", ] [project.optional-dependencies] -instruments = [ - "claude-agent-sdk >= 0.1.14", -] +instruments = ["claude-agent-sdk >= 0.1.14"] [project.entry-points.opentelemetry_instrumentor] claude-agent-sdk = "opentelemetry.instrumentation.claude_agent_sdk:ClaudeAgentSDKInstrumentor" @@ -46,11 +44,7 @@ Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" path = "src/opentelemetry/instrumentation/claude_agent_sdk/version.py" [tool.hatch.build.targets.sdist] -include = [ - "/src", - "/tests", - "/examples", -] +include = ["/src", "/tests", "/examples"] [tool.hatch.build.targets.wheel] packages = ["src/opentelemetry"] diff --git a/instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk/tests/requirements.oldest.txt index adfadef283c..833e05fb1d4 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk/tests/requirements.oldest.txt @@ -21,8 +21,8 @@ pytest==7.4.4 pytest-vcr==1.0.2 pytest-asyncio==0.21.0 wrapt==1.16.0 -opentelemetry-api==1.37 # when updating, also update in pyproject.toml -opentelemetry-sdk==1.37 # when updating, also update in pyproject.toml -opentelemetry-semantic-conventions==0.58b0 # when updating, also update in pyproject.toml +opentelemetry-api==1.39 # when updating, also update in pyproject.toml +opentelemetry-sdk==1.39 # when updating, also update in pyproject.toml +opentelemetry-semantic-conventions==0.60b0 # when updating, also update in pyproject.toml -e instrumentation-genai/opentelemetry-instrumentation-claude-agent-sdk diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index fc5939985b5..7b4fcce2241 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -26,16 +26,14 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-api ~= 1.37", - "opentelemetry-instrumentation ~= 0.58b0", - "opentelemetry-semantic-conventions ~= 0.58b0", + "opentelemetry-api ~= 1.39", + "opentelemetry-instrumentation ~= 0.60b0", + "opentelemetry-semantic-conventions ~= 0.60b0", "opentelemetry-util-genai", ] [project.optional-dependencies] -instruments = [ - "openai >= 1.26.0", -] +instruments = ["openai >= 1.26.0"] [project.entry-points.opentelemetry_instrumentor] openai = "opentelemetry.instrumentation.openai_v2:OpenAIInstrumentor" @@ -48,10 +46,7 @@ Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" path = "src/opentelemetry/instrumentation/openai_v2/version.py" [tool.hatch.build.targets.sdist] -include = [ - "/src", - "/tests", -] +include = ["/src", "/tests"] [tool.hatch.build.targets.wheel] packages = ["src/opentelemetry"] diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.oldest.txt index 2644ba47e8c..45339fb438a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.oldest.txt @@ -29,9 +29,9 @@ pytest-vcr==1.0.2 pytest-asyncio==0.21.0 wrapt==1.16.0 opentelemetry-exporter-otlp-proto-http~=1.30 -opentelemetry-api==1.37 # when updating, also update in pyproject.toml -opentelemetry-sdk==1.37 # when updating, also update in pyproject.toml -opentelemetry-semantic-conventions==0.58b0 # when updating, also update in pyproject.toml +opentelemetry-api==1.39 # when updating, also update in pyproject.toml +opentelemetry-sdk==1.39 # when updating, also update in pyproject.toml +opentelemetry-semantic-conventions==0.60b0 # when updating, also update in pyproject.toml -e instrumentation-genai/opentelemetry-instrumentation-openai-v2 -e util/opentelemetry-util-genai \ No newline at end of file diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index 1b0a444b95e..d779ac8efe2 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Add EmbeddingInvocation span lifecycle support + ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4219](#4219)) - Populate schema_url on metrics ([#4320](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4320)) - Add workflow invocation type to genAI utils @@ -41,10 +43,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3795](#3795)) - Make inputs / outputs / system instructions optional params to `on_completion`, ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3802](#3802)). - - Use a SHA256 hash of the system instructions as it's upload filename, and check +- Use a SHA256 hash of the system instructions as it's upload filename, and check if the file exists before re-uploading it, ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3814](#3814)). - ## Version 0.1b0 (2025-09-25) - Add completion hook to genai utils to implement semconv v1.37. @@ -57,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3752](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3752)) ([#3759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3759)) ([#3763](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3763)) + - Add a utility to parse the `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` environment variable. Add `gen_ai_latest_experimental` as a new value to the Sem Conv stability flag ([#3716](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3716)). diff --git a/util/opentelemetry-util-genai/README.rst b/util/opentelemetry-util-genai/README.rst index bc4b348fcf4..94806e01599 100644 --- a/util/opentelemetry-util-genai/README.rst +++ b/util/opentelemetry-util-genai/README.rst @@ -36,6 +36,18 @@ This package provides these span attributes: - `gen_ai.output.messages`: Str('[{"role": "AI", "parts": [{"content": "hello back", "type": "text"}], "finish_reason": "stop"}]') - `gen_ai.system_instructions`: Str('[{"content": "You are a helpful assistant.", "type": "text"}]') (when system instruction is provided) +This package also supports embedding invocation spans via the `embedding` context manager. +For embedding invocations, common attributes include: + +- `gen_ai.provider.name`: Str(openai) +- `gen_ai.operation.name`: Str(embeddings) +- `gen_ai.request.model`: Str(text-embedding-3-small) +- `gen_ai.embeddings.dimension.count`: Int(1536) +- `gen_ai.request.encoding_formats`: Slice(["float"]) +- `gen_ai.usage.input_tokens`: Int(24) +- `server.address`: Str(api.openai.com) +- `server.port`: Int(443) + When `EVENT_ONLY` or `SPAN_AND_EVENT` mode is enabled and a LoggerProvider is configured, the package also emits `gen_ai.client.inference.operation.details` events with structured message content (as dictionaries instead of JSON strings). Note that when using `EVENT_ONLY` diff --git a/util/opentelemetry-util-genai/pyproject.toml b/util/opentelemetry-util-genai/pyproject.toml index c9d4d388c18..f8705369c2e 100644 --- a/util/opentelemetry-util-genai/pyproject.toml +++ b/util/opentelemetry-util-genai/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-instrumentation ~= 0.58b0", - "opentelemetry-semantic-conventions ~= 0.58b0", - "opentelemetry-api>=1.31.0", + "opentelemetry-instrumentation ~= 0.60b0", + "opentelemetry-semantic-conventions ~= 0.60b0", + "opentelemetry-api>=1.39", ] [project.entry-points.opentelemetry_genai_completion_hook] @@ -46,10 +46,7 @@ Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" path = "src/opentelemetry/util/genai/version.py" [tool.hatch.build.targets.sdist] -include = [ - "/src", - "/tests", -] +include = ["/src", "/tests"] [tool.hatch.build.targets.wheel] packages = ["src/opentelemetry"] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py index 4e85799ea1e..80b801e9a1d 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py @@ -62,7 +62,7 @@ import timeit from contextlib import contextmanager -from typing import Iterator +from typing import Iterator, TypeVar from opentelemetry import context as otel_context from opentelemetry._logs import ( @@ -80,13 +80,23 @@ ) from opentelemetry.util.genai.metrics import InvocationMetricsRecorder from opentelemetry.util.genai.span_utils import ( + _apply_embedding_finish_attributes, _apply_error_attributes, _apply_llm_finish_attributes, + _get_embedding_span_name, + _get_llm_span_name, _maybe_emit_llm_event, ) -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import ( + EmbeddingInvocation, + Error, + GenAIInvocation, + LLMInvocation, +) from opentelemetry.util.genai.version import __version__ +_T = TypeVar("_T", bound=GenAIInvocation) + class TelemetryHandler: """ @@ -134,14 +144,28 @@ def _record_llm_metrics( error_type=error_type, ) - def start_llm( - self, - invocation: LLMInvocation, - ) -> LLMInvocation: - """Start an LLM invocation and create a pending span entry.""" - # Create a span and attach it as current; keep the token to detach later + @staticmethod + def _record_embedding_metrics( + invocation: EmbeddingInvocation, + span: Span | None = None, + *, + error_type: str | None = None, + ) -> None: + # Metrics recorder currently supports LLMInvocation fields only. + # Keep embedding metrics as a no-op until dedicated embedding + # metric support is added. + return + + def _start(self, invocation: _T) -> _T: + """Start a GenAI invocation and create a pending span entry.""" + if isinstance(invocation, LLMInvocation): + span_name = _get_llm_span_name(invocation) + elif isinstance(invocation, EmbeddingInvocation): + span_name = _get_embedding_span_name(invocation) + else: + span_name = "" span = self._tracer.start_span( - name=f"{invocation.operation_name} {invocation.request_model}", + name=span_name, kind=SpanKind.CLIENT, ) # Record a monotonic start timestamp (seconds) for duration @@ -153,40 +177,87 @@ def start_llm( ) return invocation - def stop_llm(self, invocation: LLMInvocation) -> LLMInvocation: # pylint: disable=no-self-use - """Finalize an LLM invocation successfully and end its span.""" + def _stop(self, invocation: _T) -> _T: + """Finalize a GenAI invocation successfully and end its span.""" if invocation.context_token is None or invocation.span is None: # TODO: Provide feedback that this invocation was not started return invocation span = invocation.span - _apply_llm_finish_attributes(span, invocation) - self._record_llm_metrics(invocation, span) - _maybe_emit_llm_event(self._logger, span, invocation) - # Detach context and end span - otel_context.detach(invocation.context_token) - span.end() + try: + if isinstance(invocation, LLMInvocation): + _apply_llm_finish_attributes(span, invocation) + self._record_llm_metrics(invocation, span) + _maybe_emit_llm_event(self._logger, span, invocation) + elif isinstance(invocation, EmbeddingInvocation): + _apply_embedding_finish_attributes(span, invocation) + self._record_embedding_metrics(invocation, span) + finally: + # Detach context and end span even if finishing fails + otel_context.detach(invocation.context_token) + span.end() return invocation - def fail_llm( # pylint: disable=no-self-use - self, invocation: LLMInvocation, error: Error - ) -> LLMInvocation: - """Fail an LLM invocation and end its span with error status.""" + def _fail(self, invocation: _T, error: Error) -> _T: + """Fail a GenAI invocation and end its span with error status.""" if invocation.context_token is None or invocation.span is None: # TODO: Provide feedback that this invocation was not started return invocation span = invocation.span - _apply_llm_finish_attributes(invocation.span, invocation) - _apply_error_attributes(invocation.span, error) - error_type = getattr(error.type, "__qualname__", None) - self._record_llm_metrics(invocation, span, error_type=error_type) - _maybe_emit_llm_event(self._logger, span, invocation, error) - # Detach context and end span - otel_context.detach(invocation.context_token) - span.end() + error_type = error.type.__qualname__ + try: + if isinstance(invocation, LLMInvocation): + _apply_llm_finish_attributes(span, invocation) + _apply_error_attributes(span, error, error_type) + self._record_llm_metrics( + invocation, span, error_type=error_type + ) + _maybe_emit_llm_event( + self._logger, span, invocation, error_type + ) + elif isinstance(invocation, EmbeddingInvocation): + _apply_embedding_finish_attributes(span, invocation) + _apply_error_attributes(span, error, error_type) + self._record_embedding_metrics( + invocation, span, error_type=error_type + ) + finally: + # Detach context and end span even if finishing fails + otel_context.detach(invocation.context_token) + span.end() return invocation + def start( + self, + invocation: _T, + ) -> _T: + """Start a GenAI invocation and create a pending span entry.""" + return self._start(invocation) + + def stop(self, invocation: _T) -> _T: + """Finalize a GenAI invocation successfully and end its span.""" + return self._stop(invocation) + + def fail(self, invocation: _T, error: Error) -> _T: + """Fail a GenAI invocation and end its span with error status.""" + return self._fail(invocation, error) + + # LLM-specific convenience methods + def start_llm(self, invocation: LLMInvocation) -> LLMInvocation: + """Start an LLM invocation and create a pending span entry.""" + return self._start(invocation) + + def stop_llm(self, invocation: LLMInvocation) -> LLMInvocation: + """Finalize an LLM invocation successfully and end its span.""" + return self._stop(invocation) + + def fail_llm( + self, invocation: LLMInvocation, error: Error + ) -> LLMInvocation: + """Fail an LLM invocation and end its span with error status.""" + return self._fail(invocation, error) + @contextmanager def llm( self, invocation: LLMInvocation | None = None @@ -211,6 +282,28 @@ def llm( raise self.stop_llm(invocation) + @contextmanager + def embedding( + self, invocation: EmbeddingInvocation | None = None + ) -> Iterator[EmbeddingInvocation]: + """Context manager for Embedding invocations. + + Only set data attributes on the invocation object, do not modify the span or context. + + Starts the span on entry. On normal exit, finalizes the invocation and ends the span. + If an exception occurs inside the context, marks the span as error, ends it, and + re-raises the original exception. + """ + if invocation is None: + invocation = EmbeddingInvocation() + self.start(invocation) + try: + yield invocation + except Exception as exc: + self.fail(invocation, Error(message=str(exc), type=type(exc))) + raise + self.stop(invocation) + def get_telemetry_handler( tracer_provider: TracerProvider | None = None, diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py index 889994436f6..ac099e3dae6 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py @@ -32,7 +32,9 @@ from opentelemetry.trace.propagation import set_span_in_context from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.genai.types import ( + EmbeddingInvocation, Error, + GenAIInvocation, InputMessage, LLMInvocation, MessagePart, @@ -68,9 +70,42 @@ def _get_llm_common_attributes( } +def _get_embedding_common_attributes( + invocation: EmbeddingInvocation, +) -> dict[str, Any]: + """Get common Embedding attributes shared by finish() and error() paths. + + Returns a dictionary of attributes. + """ + optional_attrs = ( + (server_attributes.SERVER_ADDRESS, invocation.server_address), + (server_attributes.SERVER_PORT, invocation.server_port), + ) + + return { + GenAI.GEN_AI_OPERATION_NAME: invocation.operation_name, + GenAI.GEN_AI_PROVIDER_NAME: invocation.provider, + **{key: value for key, value in optional_attrs if value is not None}, + } + + +def _get_span_name( + invocation: GenAIInvocation, +) -> str: + """Get the span name for a GenAI invocation.""" + operation_name = getattr(invocation, "operation_name", None) or "" + request_model = getattr(invocation, "request_model", None) or "" + return f"{operation_name} {request_model}".strip() + + def _get_llm_span_name(invocation: LLMInvocation) -> str: """Get the span name for an LLM invocation.""" - return f"{invocation.operation_name} {invocation.request_model}".strip() + return _get_span_name(invocation) + + +def _get_embedding_span_name(invocation: EmbeddingInvocation) -> str: + """Get the span name for an Embedding invocation.""" + return _get_span_name(invocation) def _get_llm_messages_attributes_for_span( @@ -151,7 +186,7 @@ def _maybe_emit_llm_event( logger: Logger | None, span: Span, invocation: LLMInvocation, - error: Error | None = None, + error_type: str | None = None, ) -> None: """Emit a gen_ai.client.inference.operation.details event to the logger. @@ -179,8 +214,8 @@ def _maybe_emit_llm_event( ) # Add error.type if operation ended in error - if error is not None: - attributes[error_attributes.ERROR_TYPE] = error.type.__qualname__ + if error_type is not None: + attributes[error_attributes.ERROR_TYPE] = error_type # Create and emit the event context = set_span_in_context(span, get_current()) @@ -218,13 +253,31 @@ def _apply_llm_finish_attributes( span.set_attributes(attributes) -def _apply_error_attributes(span: Span, error: Error) -> None: +def _apply_embedding_finish_attributes( + span: Span, invocation: EmbeddingInvocation +) -> None: + """Apply attributes common to embedding finish() paths.""" + # Update span name + span.update_name(_get_embedding_span_name(invocation)) + + # Build all attributes by reusing the attribute getter functions + attributes: dict[str, Any] = {} + attributes.update(_get_embedding_common_attributes(invocation)) + attributes.update(_get_embedding_request_attributes(invocation)) + attributes.update(_get_embedding_response_attributes(invocation)) + + attributes.update(invocation.attributes) + + # Set all attributes on the span + if attributes: + span.set_attributes(attributes) + + +def _apply_error_attributes(span: Span, error: Error, error_type: str) -> None: """Apply status and error attributes common to error() paths.""" span.set_status(Status(StatusCode.ERROR, error.message)) if span.is_recording(): - span.set_attribute( - error_attributes.ERROR_TYPE, error.type.__qualname__ - ) + span.set_attribute(error_attributes.ERROR_TYPE, error_type) def _get_llm_request_attributes( @@ -244,6 +297,19 @@ def _get_llm_request_attributes( return {key: value for key, value in optional_attrs if value is not None} +def _get_embedding_request_attributes( + invocation: EmbeddingInvocation, +) -> dict[str, Any]: + """Get GenAI request semantic convention attributes.""" + optional_attrs = ( + (GenAI.GEN_AI_REQUEST_MODEL, invocation.request_model), + (GenAI.GEN_AI_EMBEDDINGS_DIMENSION_COUNT, invocation.dimension_count), + (GenAI.GEN_AI_REQUEST_ENCODING_FORMATS, invocation.encoding_formats), + ) + + return {key: value for key, value in optional_attrs if value is not None} + + def _get_llm_response_attributes( invocation: LLMInvocation, ) -> dict[str, Any]: @@ -279,6 +345,18 @@ def _get_llm_response_attributes( return {key: value for key, value in optional_attrs if value is not None} +def _get_embedding_response_attributes( + invocation: EmbeddingInvocation, +) -> dict[str, Any]: + """Get GenAI response semantic convention attributes.""" + optional_attrs = ( + (GenAI.GEN_AI_RESPONSE_MODEL, invocation.response_model_name), + (GenAI.GEN_AI_USAGE_INPUT_TOKENS, invocation.input_tokens), + ) + + return {key: value for key, value in optional_attrs if value is not None} + + __all__ = [ "_apply_llm_finish_attributes", "_apply_error_attributes", @@ -287,4 +365,9 @@ def _get_llm_response_attributes( "_get_llm_response_attributes", "_get_llm_span_name", "_maybe_emit_llm_event", + "_apply_embedding_finish_attributes", + "_get_embedding_common_attributes", + "_get_embedding_request_attributes", + "_get_embedding_response_attributes", + "_get_embedding_span_name", ] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py index fc5de2cdb0c..a714e808b64 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py @@ -202,6 +202,13 @@ class GenAIInvocation: span: Span | None = None attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) + monotonic_start_s: float | None = None + """ + Monotonic start time in seconds (from timeit.default_timer) used for + duration calculations to avoid mixing clock sources. This is populated + by the TelemetryHandler when starting an invocation. + """ + @dataclass class WorkflowInvocation(GenAIInvocation): @@ -228,9 +235,8 @@ class LLMInvocation(GenAIInvocation): set by the TelemetryHandler. """ - request_model: str | None = None - # Chat by default operation_name: str = GenAI.GenAiOperationNameValues.CHAT.value + request_model: str | None = None input_messages: list[InputMessage] = field( default_factory=_new_input_messages ) @@ -267,10 +273,42 @@ class LLMInvocation(GenAIInvocation): seed: int | None = None server_address: str | None = None server_port: int | None = None - # Monotonic start time in seconds (from timeit.default_timer) used - # for duration calculations to avoid mixing clock sources. This is - # populated by the TelemetryHandler when starting an invocation. - monotonic_start_s: float | None = None + + +@dataclass +class EmbeddingInvocation(GenAIInvocation): + """ + Represents a single embedding model invocation. When creating an + EmbeddingInvocation object, only update the data attributes. The span + and context_token attributes are set by the TelemetryHandler. + """ + + operation_name: str = GenAI.GenAiOperationNameValues.EMBEDDINGS.value + request_model: str | None = None + provider: str | None = None # e.g., azure.ai.openai, openai, aws.bedrock + server_address: str | None = None + server_port: int | None = None + + # encoding_formats can be multi-value -> combinational cardinality risk. + # Keep on spans/events only. + encoding_formats: list[str] | None = None + input_tokens: int | None = None + dimension_count: int | None = None + response_model_name: str | None = None + + attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) + """ + Additional attributes to set on spans and/or events. These attributes + will not be set on metrics. + """ + + metric_attributes: dict[str, Any] = field( + default_factory=_new_str_any_dict + ) + """ + Additional attributes to set on metrics. Must be of a low cardinality. + These attributes will not be set on spans or events. + """ @dataclass diff --git a/util/opentelemetry-util-genai/tests/test_utils.py b/util/opentelemetry-util-genai/tests/test_utils.py index d229d4b4b62..ee0e63d852d 100644 --- a/util/opentelemetry-util-genai/tests/test_utils.py +++ b/util/opentelemetry-util-genai/tests/test_utils.py @@ -25,9 +25,7 @@ ) from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk._logs.export import ( - InMemoryLogExporter as InMemoryLogRecordExporter, -) -from opentelemetry.sdk._logs.export import ( + InMemoryLogExporter, SimpleLogRecordProcessor, ) from opentelemetry.sdk.trace import ReadableSpan, TracerProvider @@ -51,7 +49,7 @@ from opentelemetry.util.genai.handler import get_telemetry_handler from opentelemetry.util.genai.types import ( ContentCapturingMode, - Error, + EmbeddingInvocation, InputMessage, LLMInvocation, MessagePart, @@ -224,7 +222,7 @@ def setUp(self): tracer_provider.add_span_processor( SimpleSpanProcessor(self.span_exporter) ) - self.log_exporter = InMemoryLogRecordExporter() + self.log_exporter = InMemoryLogExporter() logger_provider = LoggerProvider() logger_provider.add_log_record_processor( SimpleLogRecordProcessor(self.log_exporter) @@ -523,6 +521,82 @@ def test_parent_child_span_relationship(self): # Parent should not have a parent (root) assert parent_span.parent is None + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="SPAN_ONLY", + emit_event="", + ) + def test_embedding_parent_child_span_relationship(self): + parent_invocation = EmbeddingInvocation( + request_model="embed-parent-model", + provider="test-provider", + input_tokens=10, + ) + child_invocation = EmbeddingInvocation( + request_model="embed-child-model", + provider="test-provider", + input_tokens=5, + ) + + self.telemetry_handler.start(parent_invocation) + assert parent_invocation.span is not None + self.telemetry_handler.start(child_invocation) + assert child_invocation.span is not None + self.telemetry_handler.stop(child_invocation) + self.telemetry_handler.stop(parent_invocation) + + spans = self.span_exporter.get_finished_spans() + assert len(spans) == 2 + child_span = next( + s for s in spans if s.name == "embeddings embed-child-model" + ) + parent_span = next( + s for s in spans if s.name == "embeddings embed-parent-model" + ) + + assert child_span.context.trace_id == parent_span.context.trace_id + assert child_span.parent is not None + assert child_span.parent.span_id == parent_span.context.span_id + assert parent_span.parent is None + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="SPAN_ONLY", + emit_event="", + ) + def test_llm_parent_embedding_child_span_relationship(self): + message = _create_input_message("hi") + chat_generation = _create_output_message("ok") + child_invocation = EmbeddingInvocation( + request_model="embed-child-model", + provider="test-provider", + input_tokens=3, + ) + + with self.telemetry_handler.llm() as parent_invocation: + for attr, value in { + "request_model": "parent-model", + "input_messages": [message], + "provider": "test-provider", + }.items(): + setattr(parent_invocation, attr, value) + self.telemetry_handler.start(child_invocation) + assert child_invocation.span is not None + self.telemetry_handler.stop(child_invocation) + parent_invocation.output_messages = [chat_generation] + + spans = self.span_exporter.get_finished_spans() + assert len(spans) == 2 + child_span = next( + s for s in spans if s.name == "embeddings embed-child-model" + ) + parent_span = next(s for s in spans if s.name == "chat parent-model") + + assert child_span.context.trace_id == parent_span.context.trace_id + assert child_span.parent is not None + assert child_span.parent.span_id == parent_span.context.span_id + assert parent_span.parent is None + def test_llm_context_manager_error_path_records_error_status_and_attrs( self, ): @@ -571,318 +645,91 @@ class BoomError(RuntimeError): }, ) - @patch_env_vars( - stability_mode="gen_ai_latest_experimental", - content_capturing="EVENT_ONLY", - emit_event="true", - ) - def test_emits_llm_event(self): - invocation = LLMInvocation( - request_model="event-model", - input_messages=[_create_input_message("test query")], - system_instruction=_create_system_instruction(), - provider="test-provider", - temperature=0.7, - max_tokens=100, - response_model_name="response-model", - response_id="event-response-id", - input_tokens=10, - output_tokens=20, - ) - - self.telemetry_handler.start_llm(invocation) - invocation.output_messages = [_create_output_message("test response")] - self.telemetry_handler.stop_llm(invocation) - - # Check that event was emitted - logs = self.log_exporter.get_finished_logs() - self.assertEqual(len(logs), 1) - log_record = logs[0].log_record - - # Verify event name - self.assertEqual( - log_record.event_name, "gen_ai.client.inference.operation.details" - ) - - # Verify event attributes - attrs = log_record.attributes - self.assertIsNotNone(attrs) - self.assertEqual(attrs[GenAI.GEN_AI_OPERATION_NAME], "chat") - self.assertEqual(attrs[GenAI.GEN_AI_REQUEST_MODEL], "event-model") - self.assertEqual(attrs[GenAI.GEN_AI_PROVIDER_NAME], "test-provider") - self.assertEqual(attrs[GenAI.GEN_AI_REQUEST_TEMPERATURE], 0.7) - self.assertEqual(attrs[GenAI.GEN_AI_REQUEST_MAX_TOKENS], 100) - self.assertEqual(attrs[GenAI.GEN_AI_RESPONSE_MODEL], "response-model") - self.assertEqual(attrs[GenAI.GEN_AI_RESPONSE_ID], "event-response-id") - self.assertEqual(attrs[GenAI.GEN_AI_USAGE_INPUT_TOKENS], 10) - self.assertEqual(attrs[GenAI.GEN_AI_USAGE_OUTPUT_TOKENS], 20) - - # Verify messages are in structured format (not JSON string) - # OpenTelemetry may convert lists to tuples, so we normalize - input_msg = _normalize_to_dict( - _normalize_to_list(attrs[GenAI.GEN_AI_INPUT_MESSAGES])[0] - ) - self.assertEqual(input_msg["role"], "Human") - self.assertEqual( - _normalize_to_list(input_msg["parts"])[0]["content"], "test query" - ) - - output_msg = _normalize_to_dict( - _normalize_to_list(attrs[GenAI.GEN_AI_OUTPUT_MESSAGES])[0] - ) - self.assertEqual(output_msg["role"], "AI") - self.assertEqual( - _normalize_to_list(output_msg["parts"])[0]["content"], - "test response", - ) - self.assertEqual(output_msg["finish_reason"], "stop") - - # Verify system instruction is present in event in structured format - sys_instr = _normalize_to_dict( - _normalize_to_list(attrs[GenAI.GEN_AI_SYSTEM_INSTRUCTIONS])[0] - ) - self.assertEqual(sys_instr["content"], "You are a helpful assistant.") - self.assertEqual(sys_instr["type"], "text") - - # Verify event context matches span context - span = _get_single_span(self.span_exporter) - self.assertIsNotNone(log_record.trace_id) - self.assertIsNotNone(log_record.span_id) - self.assertIsNotNone(span.context) - self.assertEqual(log_record.trace_id, span.context.trace_id) - self.assertEqual(log_record.span_id, span.context.span_id) - - @patch_env_vars( - stability_mode="gen_ai_latest_experimental", - content_capturing="SPAN_AND_EVENT", - emit_event="true", - ) - def test_emits_llm_event_and_span(self): - message = _create_input_message("combined test") - chat_generation = _create_output_message("combined response") - system_instruction = _create_system_instruction("System prompt here") - - invocation = LLMInvocation( - request_model="combined-model", - input_messages=[message], - system_instruction=system_instruction, - provider="test-provider", - ) - - self.telemetry_handler.start_llm(invocation) - invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) - - # Check span was created - span = _get_single_span(self.span_exporter) - span_attrs = _get_span_attributes(span) - self.assertIn(GenAI.GEN_AI_INPUT_MESSAGES, span_attrs) - - # Check event was emitted - logs = self.log_exporter.get_finished_logs() - self.assertEqual(len(logs), 1) - log_record = logs[0].log_record - self.assertEqual( - log_record.event_name, "gen_ai.client.inference.operation.details" - ) - self.assertIn(GenAI.GEN_AI_INPUT_MESSAGES, log_record.attributes) - # Verify system instruction in both span and event - self.assertIn(GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, span_attrs) - span_system = json.loads(span_attrs[GenAI.GEN_AI_SYSTEM_INSTRUCTIONS]) - self.assertEqual(span_system[0]["content"], "System prompt here") - event_attrs = log_record.attributes - self.assertIn(GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, event_attrs) - event_system = event_attrs[GenAI.GEN_AI_SYSTEM_INSTRUCTIONS] - event_system_list = ( - list(event_system) - if isinstance(event_system, tuple) - else event_system - ) - event_sys_instr = ( - dict(event_system_list[0]) - if isinstance(event_system_list[0], tuple) - else event_system_list[0] - ) - self.assertEqual(event_sys_instr["content"], "System prompt here") - # Verify event context matches span context - span = _get_single_span(self.span_exporter) - self.assertIsNotNone(log_record.trace_id) - self.assertIsNotNone(log_record.span_id) - self.assertIsNotNone(span.context) - self.assertEqual(log_record.trace_id, span.context.trace_id) - self.assertEqual(log_record.span_id, span.context.span_id) - - @patch_env_vars( - stability_mode="gen_ai_latest_experimental", - content_capturing="EVENT_ONLY", - emit_event="true", - ) - def test_emits_llm_event_with_error(self): - class TestError(RuntimeError): + def test_embedding_context_manager_error_path_records_error_status_and_attrs( + self, + ): + class BoomError(RuntimeError): pass - message = _create_input_message("error test") - invocation = LLMInvocation( - request_model="error-model", - input_messages=[message], + invocation = EmbeddingInvocation( + request_model="embed-model", provider="test-provider", + dimension_count=1536, + input_tokens=7, + server_address="embed.example.com", + server_port=443, + attributes={"custom_embed_attr": "value"}, ) - self.telemetry_handler.start_llm(invocation) - error = Error(message="Test error occurred", type=TestError) - self.telemetry_handler.fail_llm(invocation, error) - - # Check event was emitted - logs = self.log_exporter.get_finished_logs() - self.assertEqual(len(logs), 1) - log_record = logs[0].log_record - attrs = log_record.attributes + with self.assertRaises(BoomError): + with self.telemetry_handler.embedding(invocation): + invocation.response_model_name = "embed-response-model" + raise BoomError("embedding boom") - # Verify error attribute is present - self.assertEqual( - attrs[error_attributes.ERROR_TYPE], TestError.__qualname__ - ) - self.assertEqual(attrs[GenAI.GEN_AI_OPERATION_NAME], "chat") - self.assertEqual(attrs[GenAI.GEN_AI_REQUEST_MODEL], "error-model") - # Verify event context matches span context span = _get_single_span(self.span_exporter) - self.assertIsNotNone(log_record.trace_id) - self.assertIsNotNone(log_record.span_id) - self.assertIsNotNone(span.context) - self.assertEqual(log_record.trace_id, span.context.trace_id) - self.assertEqual(log_record.span_id, span.context.span_id) - - @patch_env_vars( - stability_mode="gen_ai_latest_experimental", - content_capturing="EVENT_ONLY", - emit_event="false", - ) - def test_does_not_emit_llm_event_when_emit_event_false(self): - message = _create_input_message("emit false test") - chat_generation = _create_output_message("emit false response") - - invocation = LLMInvocation( - request_model="emit-false-model", - input_messages=[message], - provider="test-provider", - ) - - self.telemetry_handler.start_llm(invocation) - invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) - - # Check no event was emitted - logs = self.log_exporter.get_finished_logs() - self.assertEqual(len(logs), 0) - - @patch_env_vars( - stability_mode="gen_ai_latest_experimental", - content_capturing="NO_CONTENT", - emit_event="", - ) - def test_does_not_emit_llm_event_by_default_for_no_content(self): - """Test that event is not emitted by default when content_capturing is NO_CONTENT and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", + assert span.status.status_code == StatusCode.ERROR + _assert_span_time_order(span) + span_attrs = _get_span_attributes(span) + _assert_span_attributes( + span_attrs, + { + GenAI.GEN_AI_OPERATION_NAME: "embeddings", + GenAI.GEN_AI_REQUEST_MODEL: "embed-model", + GenAI.GEN_AI_PROVIDER_NAME: "test-provider", + GenAI.GEN_AI_EMBEDDINGS_DIMENSION_COUNT: 1536, + GenAI.GEN_AI_USAGE_INPUT_TOKENS: 7, + GenAI.GEN_AI_RESPONSE_MODEL: "embed-response-model", + server_attributes.SERVER_ADDRESS: "embed.example.com", + server_attributes.SERVER_PORT: 443, + "custom_embed_attr": "value", + error_attributes.ERROR_TYPE: BoomError.__qualname__, + }, ) - self.telemetry_handler.start_llm(invocation) - invocation.output_messages = [ - _create_output_message("default response") - ] - self.telemetry_handler.stop_llm(invocation) - - # Check that no event was emitted (NO_CONTENT defaults to False) - logs = self.log_exporter.get_finished_logs() - self.assertEqual(len(logs), 0) - @patch_env_vars( stability_mode="gen_ai_latest_experimental", content_capturing="SPAN_ONLY", emit_event="", ) - def test_does_not_emit_llm_event_by_default_for_span_only(self): - """Test that event is not emitted by default when content_capturing is SPAN_ONLY and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", - ) - - self.telemetry_handler.start_llm(invocation) - invocation.output_messages = [ - _create_output_message("default response") - ] - self.telemetry_handler.stop_llm(invocation) - - # Check that no event was emitted (SPAN_ONLY defaults to False) - logs = self.log_exporter.get_finished_logs() - self.assertEqual(len(logs), 0) - - @patch_env_vars( - stability_mode="gen_ai_latest_experimental", - content_capturing="EVENT_ONLY", - emit_event="", - ) - def test_emits_llm_event_by_default_for_event_only(self): - """Test that event is emitted by default when content_capturing is EVENT_ONLY and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", - ) - - self.telemetry_handler.start_llm(invocation) - invocation.output_messages = [ - _create_output_message("default response") - ] - self.telemetry_handler.stop_llm(invocation) - - # Check that event was emitted (EVENT_ONLY defaults to True) - logs = self.log_exporter.get_finished_logs() - self.assertEqual(len(logs), 1) - log_record = logs[0].log_record - self.assertEqual( - log_record.event_name, "gen_ai.client.inference.operation.details" - ) - - @patch_env_vars( - stability_mode="gen_ai_latest_experimental", - content_capturing="SPAN_AND_EVENT", - emit_event="", - ) - def test_emits_llm_event_by_default_for_span_and_event(self): - """Test that event is emitted by default when content_capturing is SPAN_AND_EVENT and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - message = _create_input_message("span and event test") - chat_generation = _create_output_message("span and event response") - system_instruction = _create_system_instruction("System prompt") - - invocation = LLMInvocation( - request_model="span-and-event-model", - input_messages=[message], - system_instruction=system_instruction, + def test_embedding_manual_start_and_stop_creates_span(self): + invocation = EmbeddingInvocation( + request_model="embed-model", provider="test-provider", + dimension_count=1536, + encoding_formats=["float"], + input_tokens=123, + server_address="custom.server.com", + server_port=42, + attributes={"custom_embed_attr": "value"}, ) - self.telemetry_handler.start_llm(invocation) - invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) + self.telemetry_handler.start(invocation) + assert invocation.span is not None + invocation.attributes.update({"extra_embed": "info"}) + invocation.metric_attributes = {"should not be on span": "value"} + self.telemetry_handler.stop(invocation) - # Check span was created span = _get_single_span(self.span_exporter) - span_attrs = _get_span_attributes(span) - self.assertIn(GenAI.GEN_AI_INPUT_MESSAGES, span_attrs) + self.assertEqual(span.name, "embeddings embed-model") + self.assertEqual(span.kind, trace.SpanKind.CLIENT) + _assert_span_time_order(span) - # Check that event was emitted (SPAN_AND_EVENT defaults to True) - logs = self.log_exporter.get_finished_logs() - self.assertEqual(len(logs), 1) - log_record = logs[0].log_record - self.assertEqual( - log_record.event_name, "gen_ai.client.inference.operation.details" + attrs = _get_span_attributes(span) + _assert_span_attributes( + attrs, + { + GenAI.GEN_AI_OPERATION_NAME: "embeddings", + GenAI.GEN_AI_REQUEST_MODEL: "embed-model", + GenAI.GEN_AI_PROVIDER_NAME: "test-provider", + GenAI.GEN_AI_EMBEDDINGS_DIMENSION_COUNT: 1536, + GenAI.GEN_AI_REQUEST_ENCODING_FORMATS: ("float",), + GenAI.GEN_AI_USAGE_INPUT_TOKENS: 123, + server_attributes.SERVER_ADDRESS: "custom.server.com", + server_attributes.SERVER_PORT: 42, + "custom_embed_attr": "value", + "extra_embed": "info", + }, ) - self.assertIn(GenAI.GEN_AI_INPUT_MESSAGES, log_record.attributes) class AnyNonNone: diff --git a/util/opentelemetry-util-genai/tests/test_utils_events.py b/util/opentelemetry-util-genai/tests/test_utils_events.py new file mode 100644 index 00000000000..20b3300c62c --- /dev/null +++ b/util/opentelemetry-util-genai/tests/test_utils_events.py @@ -0,0 +1,380 @@ +# 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. + +import json +import unittest + +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import ( + InMemoryLogExporter, + SimpleLogRecordProcessor, +) +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.semconv.attributes import error_attributes +from opentelemetry.util.genai.handler import get_telemetry_handler +from opentelemetry.util.genai.types import Error, LLMInvocation + +from .test_utils import ( + _create_input_message, + _create_output_message, + _create_system_instruction, + _get_single_span, + _get_span_attributes, + _normalize_to_dict, + _normalize_to_list, + patch_env_vars, +) + + +class TestTelemetryHandlerEvents(unittest.TestCase): + def setUp(self): + self.span_exporter = InMemorySpanExporter() + tracer_provider = TracerProvider() + tracer_provider.add_span_processor( + SimpleSpanProcessor(self.span_exporter) + ) + self.log_exporter = InMemoryLogExporter() + logger_provider = LoggerProvider() + logger_provider.add_log_record_processor( + SimpleLogRecordProcessor(self.log_exporter) + ) + self.telemetry_handler = get_telemetry_handler( + tracer_provider=tracer_provider, logger_provider=logger_provider + ) + + def tearDown(self): + self.span_exporter.clear() + self.log_exporter.clear() + if hasattr(get_telemetry_handler, "_default_handler"): + delattr(get_telemetry_handler, "_default_handler") + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="EVENT_ONLY", + emit_event="true", + ) + def test_emits_llm_event(self): + invocation = LLMInvocation( + request_model="event-model", + input_messages=[_create_input_message("test query")], + system_instruction=_create_system_instruction(), + provider="test-provider", + temperature=0.7, + max_tokens=100, + response_model_name="response-model", + response_id="event-response-id", + input_tokens=10, + output_tokens=20, + ) + + self.telemetry_handler.start_llm(invocation) + invocation.output_messages = [_create_output_message("test response")] + self.telemetry_handler.stop_llm(invocation) + + # Check that event was emitted + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 1) + log_record = logs[0].log_record + + # Verify event name + self.assertEqual( + log_record.event_name, "gen_ai.client.inference.operation.details" + ) + + # Verify event attributes + attrs = log_record.attributes + self.assertIsNotNone(attrs) + self.assertEqual(attrs[GenAI.GEN_AI_OPERATION_NAME], "chat") + self.assertEqual(attrs[GenAI.GEN_AI_REQUEST_MODEL], "event-model") + self.assertEqual(attrs[GenAI.GEN_AI_PROVIDER_NAME], "test-provider") + self.assertEqual(attrs[GenAI.GEN_AI_REQUEST_TEMPERATURE], 0.7) + self.assertEqual(attrs[GenAI.GEN_AI_REQUEST_MAX_TOKENS], 100) + self.assertEqual(attrs[GenAI.GEN_AI_RESPONSE_MODEL], "response-model") + self.assertEqual(attrs[GenAI.GEN_AI_RESPONSE_ID], "event-response-id") + self.assertEqual(attrs[GenAI.GEN_AI_USAGE_INPUT_TOKENS], 10) + self.assertEqual(attrs[GenAI.GEN_AI_USAGE_OUTPUT_TOKENS], 20) + + # Verify messages are in structured format (not JSON string) + # OpenTelemetry may convert lists to tuples, so we normalize + input_msg = _normalize_to_dict( + _normalize_to_list(attrs[GenAI.GEN_AI_INPUT_MESSAGES])[0] + ) + self.assertEqual(input_msg["role"], "Human") + self.assertEqual( + _normalize_to_list(input_msg["parts"])[0]["content"], "test query" + ) + + output_msg = _normalize_to_dict( + _normalize_to_list(attrs[GenAI.GEN_AI_OUTPUT_MESSAGES])[0] + ) + self.assertEqual(output_msg["role"], "AI") + self.assertEqual( + _normalize_to_list(output_msg["parts"])[0]["content"], + "test response", + ) + self.assertEqual(output_msg["finish_reason"], "stop") + + # Verify system instruction is present in event in structured format + sys_instr = _normalize_to_dict( + _normalize_to_list(attrs[GenAI.GEN_AI_SYSTEM_INSTRUCTIONS])[0] + ) + self.assertEqual(sys_instr["content"], "You are a helpful assistant.") + self.assertEqual(sys_instr["type"], "text") + + # Verify event context matches span context + span = _get_single_span(self.span_exporter) + self.assertIsNotNone(log_record.trace_id) + self.assertIsNotNone(log_record.span_id) + self.assertIsNotNone(span.context) + self.assertEqual(log_record.trace_id, span.context.trace_id) + self.assertEqual(log_record.span_id, span.context.span_id) + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="SPAN_AND_EVENT", + emit_event="true", + ) + def test_emits_llm_event_and_span(self): + message = _create_input_message("combined test") + chat_generation = _create_output_message("combined response") + system_instruction = _create_system_instruction("System prompt here") + + invocation = LLMInvocation( + request_model="combined-model", + input_messages=[message], + system_instruction=system_instruction, + provider="test-provider", + ) + + self.telemetry_handler.start_llm(invocation) + invocation.output_messages = [chat_generation] + self.telemetry_handler.stop_llm(invocation) + + # Check span was created + span = _get_single_span(self.span_exporter) + span_attrs = _get_span_attributes(span) + self.assertIn(GenAI.GEN_AI_INPUT_MESSAGES, span_attrs) + + # Check event was emitted + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 1) + log_record = logs[0].log_record + self.assertEqual( + log_record.event_name, "gen_ai.client.inference.operation.details" + ) + self.assertIn(GenAI.GEN_AI_INPUT_MESSAGES, log_record.attributes) + # Verify system instruction in both span and event + self.assertIn(GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, span_attrs) + span_system = json.loads(span_attrs[GenAI.GEN_AI_SYSTEM_INSTRUCTIONS]) + self.assertEqual(span_system[0]["content"], "System prompt here") + event_attrs = log_record.attributes + self.assertIn(GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, event_attrs) + event_system = event_attrs[GenAI.GEN_AI_SYSTEM_INSTRUCTIONS] + event_system_list = ( + list(event_system) + if isinstance(event_system, tuple) + else event_system + ) + event_sys_instr = ( + dict(event_system_list[0]) + if isinstance(event_system_list[0], tuple) + else event_system_list[0] + ) + self.assertEqual(event_sys_instr["content"], "System prompt here") + # Verify event context matches span context + span = _get_single_span(self.span_exporter) + self.assertIsNotNone(log_record.trace_id) + self.assertIsNotNone(log_record.span_id) + self.assertIsNotNone(span.context) + self.assertEqual(log_record.trace_id, span.context.trace_id) + self.assertEqual(log_record.span_id, span.context.span_id) + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="EVENT_ONLY", + emit_event="true", + ) + def test_emits_llm_event_with_error(self): + class TestError(RuntimeError): + pass + + message = _create_input_message("error test") + invocation = LLMInvocation( + request_model="error-model", + input_messages=[message], + provider="test-provider", + ) + + self.telemetry_handler.start_llm(invocation) + error = Error(message="Test error occurred", type=TestError) + self.telemetry_handler.fail_llm(invocation, error) + + # Check event was emitted + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 1) + log_record = logs[0].log_record + attrs = log_record.attributes + + # Verify error attribute is present + self.assertEqual( + attrs[error_attributes.ERROR_TYPE], TestError.__qualname__ + ) + self.assertEqual(attrs[GenAI.GEN_AI_OPERATION_NAME], "chat") + self.assertEqual(attrs[GenAI.GEN_AI_REQUEST_MODEL], "error-model") + # Verify event context matches span context + span = _get_single_span(self.span_exporter) + self.assertIsNotNone(log_record.trace_id) + self.assertIsNotNone(log_record.span_id) + self.assertIsNotNone(span.context) + self.assertEqual(log_record.trace_id, span.context.trace_id) + self.assertEqual(log_record.span_id, span.context.span_id) + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="EVENT_ONLY", + emit_event="false", + ) + def test_does_not_emit_llm_event_when_emit_event_false(self): + message = _create_input_message("emit false test") + chat_generation = _create_output_message("emit false response") + + invocation = LLMInvocation( + request_model="emit-false-model", + input_messages=[message], + provider="test-provider", + ) + + self.telemetry_handler.start_llm(invocation) + invocation.output_messages = [chat_generation] + self.telemetry_handler.stop_llm(invocation) + + # Check no event was emitted + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 0) + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="NO_CONTENT", + emit_event="", + ) + def test_does_not_emit_llm_event_by_default_for_no_content(self): + """Test that event is not emitted by default when content_capturing is NO_CONTENT and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" + invocation = LLMInvocation( + request_model="default-model", + input_messages=[_create_input_message("default test")], + provider="test-provider", + ) + + self.telemetry_handler.start_llm(invocation) + invocation.output_messages = [ + _create_output_message("default response") + ] + self.telemetry_handler.stop_llm(invocation) + + # Check that no event was emitted (NO_CONTENT defaults to False) + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 0) + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="SPAN_ONLY", + emit_event="", + ) + def test_does_not_emit_llm_event_by_default_for_span_only(self): + """Test that event is not emitted by default when content_capturing is SPAN_ONLY and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" + invocation = LLMInvocation( + request_model="default-model", + input_messages=[_create_input_message("default test")], + provider="test-provider", + ) + + self.telemetry_handler.start_llm(invocation) + invocation.output_messages = [ + _create_output_message("default response") + ] + self.telemetry_handler.stop_llm(invocation) + + # Check that no event was emitted (SPAN_ONLY defaults to False) + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 0) + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="EVENT_ONLY", + emit_event="", + ) + def test_emits_llm_event_by_default_for_event_only(self): + """Test that event is emitted by default when content_capturing is EVENT_ONLY and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" + invocation = LLMInvocation( + request_model="default-model", + input_messages=[_create_input_message("default test")], + provider="test-provider", + ) + + self.telemetry_handler.start_llm(invocation) + invocation.output_messages = [ + _create_output_message("default response") + ] + self.telemetry_handler.stop_llm(invocation) + + # Check that event was emitted (EVENT_ONLY defaults to True) + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 1) + log_record = logs[0].log_record + self.assertEqual( + log_record.event_name, "gen_ai.client.inference.operation.details" + ) + + @patch_env_vars( + stability_mode="gen_ai_latest_experimental", + content_capturing="SPAN_AND_EVENT", + emit_event="", + ) + def test_emits_llm_event_by_default_for_span_and_event(self): + """Test that event is emitted by default when content_capturing is SPAN_AND_EVENT and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" + message = _create_input_message("span and event test") + chat_generation = _create_output_message("span and event response") + system_instruction = _create_system_instruction("System prompt") + + invocation = LLMInvocation( + request_model="span-and-event-model", + input_messages=[message], + system_instruction=system_instruction, + provider="test-provider", + ) + + self.telemetry_handler.start_llm(invocation) + invocation.output_messages = [chat_generation] + self.telemetry_handler.stop_llm(invocation) + + # Check span was created + span = _get_single_span(self.span_exporter) + span_attrs = _get_span_attributes(span) + self.assertIn(GenAI.GEN_AI_INPUT_MESSAGES, span_attrs) + + # Check that event was emitted (SPAN_AND_EVENT defaults to True) + logs = self.log_exporter.get_finished_logs() + self.assertEqual(len(logs), 1) + log_record = logs[0].log_record + self.assertEqual( + log_record.event_name, "gen_ai.client.inference.operation.details" + ) + self.assertIn(GenAI.GEN_AI_INPUT_MESSAGES, log_record.attributes) From a4285851245f56ad261e348d5e1b87ecdcb2d95f Mon Sep 17 00:00:00 2001 From: Keith Decker <47755047+keith-decker@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:53:47 -0600 Subject: [PATCH 39/78] GenAI Utils | Update ToolCall Type (#4218) --- .../instrumentation/anthropic/utils.py | 10 +- .../pyproject.toml | 8 +- .../instrumentation/google_genai/message.py | 45 +++---- .../tests/requirements.oldest.txt | 10 +- .../langchain/callback_handler.py | 11 +- .../instrumentation/openai_v2/patch.py | 4 +- .../instrumentation/openai_v2/utils.py | 8 +- .../pyproject.toml | 8 +- .../instrumentation/vertexai/utils.py | 44 ++++--- .../tests/requirements.oldest.txt | 11 +- .../test_chat_completions_experimental.py | 8 +- util/opentelemetry-util-genai/CHANGELOG.md | 2 + .../src/opentelemetry/util/genai/types.py | 110 +++++++++++++++- .../tests/test_toolcall.py | 118 ++++++++++++++++++ .../tests/test_upload.py | 2 +- 15 files changed, 316 insertions(+), 83 deletions(-) create mode 100644 util/opentelemetry-util-genai/tests/test_toolcall.py diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/utils.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/utils.py index 9914a55a227..7399b8831b1 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/utils.py @@ -38,7 +38,7 @@ MessagePart, Reasoning, Text, - ToolCall, + ToolCallRequest, ToolCallResponse, ) @@ -114,7 +114,7 @@ def _convert_dict_block_to_part( if block_type == "tool_use": inp = block.get("input") - return ToolCall( + return ToolCallRequest( arguments=inp if isinstance(inp, dict) else None, name=str(block.get("name", "")), id=str(block.get("id", "")), @@ -144,7 +144,9 @@ def _convert_content_block_to_part( return Text(content=block.text) if isinstance(block, (ToolUseBlock, ServerToolUseBlock)): - return ToolCall(arguments=block.input, name=block.name, id=block.id) + return ToolCallRequest( + arguments=block.input, name=block.name, id=block.id + ) if isinstance(block, (ThinkingBlock, RedactedThinkingBlock)): content = ( @@ -229,7 +231,7 @@ def stream_block_state_to_part(state: StreamBlockState) -> MessagePart | None: arguments = json.loads(state.input_json) except ValueError: arguments = state.input_json - return ToolCall( + return ToolCallRequest( arguments=arguments, name=state.tool_name, id=state.tool_id, diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml index a63b28d8b49..87b30343e33 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml @@ -39,10 +39,10 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-api ~=1.37", - "opentelemetry-instrumentation >=0.58b0, <2", - "opentelemetry-semantic-conventions >=0.58b0, <2", - "opentelemetry-util-genai >= 0.3b0, <0.4b0", + "opentelemetry-api ~=1.39", + "opentelemetry-instrumentation >=0.60b0, <2", + "opentelemetry-semantic-conventions >=0.60b0, <2", + "opentelemetry-util-genai >= 0.4b0.dev, <0.5b0", ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/message.py b/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/message.py index 29ef112a6f9..a7349f0c83d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/message.py +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/message.py @@ -15,20 +15,20 @@ from __future__ import annotations import logging -from dataclasses import dataclass from enum import Enum -from typing import Literal from google.genai import types as genai_types from opentelemetry.util.genai.types import ( + Blob, FinishReason, InputMessage, MessagePart, OutputMessage, Text, - ToolCall, + ToolCallRequest, ToolCallResponse, + Uri, ) @@ -39,23 +39,6 @@ class Role(str, Enum): TOOL = "tool" -@dataclass -class BlobPart: - data: bytes - mime_type: str - type: Literal["blob"] = "blob" - - -@dataclass -class FileDataPart: - mime_type: str - uri: str - type: Literal["file_data"] = "file_data" - - class Config: - extra = "allow" - - _logger = logging.getLogger(__name__) @@ -121,16 +104,26 @@ def tool_call_id(name: str | None) -> str: if (text := part.text) is not None: return Text(content=text) - if data := part.inline_data: - return BlobPart(mime_type=data.mime_type or "", data=data.data or b"") + if inline_data := part.inline_data: + mime_type = inline_data.mime_type or "" + modality = mime_type.split("/")[0] if mime_type else "" + return Blob( + mime_type=mime_type, + modality=modality, + content=inline_data.data or b"", + ) - if data := part.file_data: - return FileDataPart( - mime_type=data.mime_type or "", uri=data.file_uri or "" + if file_data := part.file_data: + mime_type = file_data.mime_type or "" + modality = mime_type.split("/")[0] if mime_type else "" + return Uri( + mime_type=mime_type, + modality=modality, + uri=file_data.file_uri or "", ) if call := part.function_call: - return ToolCall( + return ToolCallRequest( id=call.id or tool_call_id(call.name), name=call.name or "", arguments=call.args, diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/requirements.oldest.txt index 357bbeccb37..092a723ec4e 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/requirements.oldest.txt @@ -21,11 +21,11 @@ pytest-vcr==1.0.2 google-auth==2.15.0 google-genai==1.32.0 -opentelemetry-api==1.37.0 -opentelemetry-sdk==1.37.0 -opentelemetry-semantic-conventions==0.58b0 -opentelemetry-instrumentation==0.58b0 -opentelemetry-util-genai[upload]==0.3b0 +opentelemetry-api==1.39.0 +opentelemetry-sdk==1.39.0 +opentelemetry-semantic-conventions==0.60b0 +opentelemetry-instrumentation==0.60b0 +-e util/opentelemetry-util-genai[upload] fsspec==2025.9.0 diff --git a/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py b/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py index 8f642567ca1..d694857da44 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py +++ b/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py @@ -14,7 +14,7 @@ from __future__ import annotations -from typing import Any, Optional +from typing import Any, Optional, cast from uuid import UUID from langchain_core.callbacks import BaseCallbackHandler @@ -29,6 +29,7 @@ Error, InputMessage, LLMInvocation, + MessagePart, OutputMessage, Text, ) @@ -133,7 +134,11 @@ def on_chat_model_start( Text(content=text_value, type="text") ) - input_messages.append(InputMessage(parts=parts, role=role)) + input_messages.append( + InputMessage( + parts=cast(list[MessagePart], parts), role=role + ) + ) llm_invocation = LLMInvocation( request_model=request_model, @@ -206,7 +211,7 @@ def on_llm_end( role = chat_generation.message.type output_message = OutputMessage( role=role, - parts=parts, + parts=cast(list[MessagePart], parts), finish_reason=finish_reason, ) output_messages.append(output_message) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index 2c8c1b4c710..996c91c04df 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -39,7 +39,7 @@ LLMInvocation, OutputMessage, Text, - ToolCall, + ToolCallRequest, ) from .instruments import Instruments @@ -914,7 +914,7 @@ def _set_output_messages(self): arguments = json.loads(arguments_str) except json.JSONDecodeError: arguments = arguments_str - tool_call_part = ToolCall( + tool_call_part = ToolCallRequest( name=tool_call.function_name, id=tool_call.tool_call_id, arguments=arguments, diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index 7e5d2307caf..6afca130b6e 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -41,7 +41,7 @@ LLMInvocation, OutputMessage, Text, - ToolCall, + ToolCallRequest, ToolCallResponse, ) @@ -452,7 +452,7 @@ def _prepare_input_messages(messages) -> List[InputMessage]: return chat_messages -def extract_tool_calls_new(tool_calls) -> list[ToolCall]: +def extract_tool_calls_new(tool_calls) -> list[ToolCallRequest]: parts = [] for tool_call in tool_calls: call_id = get_property_value(tool_call, "id") @@ -470,7 +470,9 @@ def extract_tool_calls_new(tool_calls) -> list[ToolCall]: arguments = arguments_str # TODO: support custom - parts.append(ToolCall(id=call_id, name=func_name, arguments=arguments)) + parts.append( + ToolCallRequest(id=call_id, name=func_name, arguments=arguments) + ) return parts diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml index 3d715a2a872..e6090642f6d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml @@ -26,10 +26,10 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-api ~= 1.37", - "opentelemetry-instrumentation ~= 0.58b0", - "opentelemetry-semantic-conventions ~= 0.58b0", - "opentelemetry-util-genai >= 0.2b0, <0.4b0", + "opentelemetry-api ~= 1.39", + "opentelemetry-instrumentation ~= 0.60b0", + "opentelemetry-semantic-conventions ~= 0.60b0", + "opentelemetry-util-genai >= 0.4b0.dev, <0.5b0", ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py index 3221cdf9bcf..9686d0dd7ac 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py @@ -52,12 +52,14 @@ ) from opentelemetry.semconv.attributes import server_attributes from opentelemetry.util.genai.types import ( + Blob, ContentCapturingMode, FinishReason, MessagePart, Text, - ToolCall, + ToolCallRequest, ToolCallResponse, + Uri, ) from opentelemetry.util.genai.utils import get_content_capturing_mode from opentelemetry.util.types import AnyValue, AttributeValue @@ -308,21 +310,15 @@ def request_to_events( yield user_event(role=content.role, content=request_content) -@dataclass -class BlobPart: - data: bytes - mime_type: str - type: Literal["blob"] = "blob" - - -@dataclass -class FileDataPart: - mime_type: str - uri: str - type: Literal["file_data"] = "file_data" - - class Config: - extra = "allow" +def _modality_from_mime_type(mime_type: str) -> str: + """Infer modality from MIME type prefix.""" + if mime_type.startswith("image/"): + return "image" + if mime_type.startswith("video/"): + return "video" + if mime_type.startswith("audio/"): + return "audio" + return mime_type def convert_content_to_message_parts( @@ -341,7 +337,7 @@ def convert_content_to_message_parts( elif "function_call" in part: part = part.function_call parts.append( - ToolCall( + ToolCallRequest( id=f"{part.name}_{idx}", name=part.name, arguments=json_format.MessageToDict( @@ -353,14 +349,22 @@ def convert_content_to_message_parts( parts.append(Text(content=part.text)) elif "inline_data" in part: part = part.inline_data + mime_type = part.mime_type or "" parts.append( - BlobPart(mime_type=part.mime_type or "", data=part.data or b"") + Blob( + mime_type=mime_type, + modality=_modality_from_mime_type(mime_type), + content=part.data or b"", + ) ) elif "file_data" in part: part = part.file_data + mime_type = part.mime_type or "" parts.append( - FileDataPart( - mime_type=part.mime_type or "", uri=part.file_uri or "" + Uri( + mime_type=mime_type, + modality=_modality_from_mime_type(mime_type), + uri=part.file_uri or "", ) ) else: diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt index 5b5c7e8f671..d02e3dc8e47 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt @@ -65,11 +65,12 @@ grpcio>=1.75.1 ; python_version >= "3.14" shapely==2.0.6 ; python_version < "3.10" shapely==2.1.2 ; python_version >= "3.10" # when updating, also update in pyproject.toml -opentelemetry-api==1.37 -opentelemetry-sdk==1.37 -opentelemetry-semantic-conventions==0.58b0 -opentelemetry-instrumentation==0.58b0 -opentelemetry-util-genai[upload]==0.2b0 +opentelemetry-api==1.39 +opentelemetry-sdk==1.39 +opentelemetry-semantic-conventions==0.60b0 +opentelemetry-instrumentation==0.60b0 +# opentelemetry-util-genai[upload]==0.2b0 +-e util/opentelemetry-util-genai[upload] fsspec==2025.9.0 -e instrumentation-genai/opentelemetry-instrumentation-vertexai[instruments] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions_experimental.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions_experimental.py index 5613f551a64..617d9a81c93 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions_experimental.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions_experimental.py @@ -74,7 +74,7 @@ def test_generate_content_with_files( "gen_ai.usage.output_tokens": 5, "server.address": "us-central1-aiplatform.googleapis.com", "server.port": 443, - "gen_ai.input.messages": '[{"role":"user","parts":[{"content":"Say this is a test","type":"text"},{"mime_type":"image/jpeg","uri":"https://images.pdimagearchive.org/collections/microscopic-delights/1lede-0021.jpg","type":"file_data"},{"data":"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==","mime_type":"image/jpeg","type":"blob"}]}]', + "gen_ai.input.messages": '[{"role":"user","parts":[{"content":"Say this is a test","type":"text"},{"mime_type":"image/jpeg","modality":"image","uri":"https://images.pdimagearchive.org/collections/microscopic-delights/1lede-0021.jpg","type":"uri"},{"mime_type":"image/jpeg","modality":"image","content":"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==","type":"blob"}]}]', "gen_ai.output.messages": '[{"role":"model","parts":[{"content":"This is a test.","type":"text"}],"finish_reason":"stop"}]', } @@ -97,12 +97,14 @@ def test_generate_content_with_files( {"content": "Say this is a test", "type": "text"}, { "mime_type": "image/jpeg", + "modality": "image", "uri": "https://images.pdimagearchive.org/collections/microscopic-delights/1lede-0021.jpg", - "type": "file_data", + "type": "uri", }, { - "data": b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\x00\x00\x00\x05\x08\x06\x00\x00\x00\x8do&\xe5\x00\x00\x00\x1cIDAT\x08\xd7c\xf8\xff\xff?\xc3\x7f\x06 \x05\xc3 \x12\x84\xd01\xf1\x82X\xcd\x04\x00\x0e\xf55\xcb\xd1\x8e\x0e\x1f\x00\x00\x00\x00IEND\xaeB`\x82", "mime_type": "image/jpeg", + "modality": "image", + "content": b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\x00\x00\x00\x05\x08\x06\x00\x00\x00\x8do&\xe5\x00\x00\x00\x1cIDAT\x08\xd7c\xf8\xff\xff?\xc3\x7f\x06 \x05\xc3 \x12\x84\xd01\xf1\x82X\xcd\x04\x00\x0e\xf55\xcb\xd1\x8e\x0e\x1f\x00\x00\x00\x00IEND\xaeB`\x82", "type": "blob", }, ), diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index d779ac8efe2..565a18d5870 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Enrich ToolCall type, breaking change: usage of ToolCall class renamed to ToolCallRequest + ([#4218](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4218)) - Add EmbeddingInvocation span lifecycle support ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4219](#4219)) - Populate schema_url on metrics diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py index a714e808b64..538d61490bf 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py @@ -30,6 +30,17 @@ ContextToken: TypeAlias = Token[Context] +@dataclass() +class GenericPart: + """Used for provider-specific message part types that don't match + the standard MessagePart types defined in semantic conventions. Wrap custom + types with GenericPart(value=...) to explicitly opt-in to non-standard types. + This will be removed in a future version when all instrumentations use core types.""" + + value: Any + type: Literal["generic"] = "generic" + + class ContentCapturingMode(Enum): # Do not capture content (default). NO_CONTENT = 0 @@ -42,8 +53,11 @@ class ContentCapturingMode(Enum): @dataclass() -class ToolCall: - """Represents a tool call requested by the model +class ToolCallRequest: + """Represents a tool call requested by the model (message part only). + + Use this for tool calls in message history. For execution tracking with spans + and metrics, use ToolCall instead. This model is specified as part of semconv in `GenAI messages Python models - ToolCallRequestPart `__. @@ -68,6 +82,41 @@ class ToolCallResponse: type: Literal["tool_call_response"] = "tool_call_response" +@dataclass() +class ServerToolCall: + """Represents a server-side tool call invocation. + + Server tool calls are executed by the model provider on the server side rather + than by the client application. Provider-specific tools (e.g., code_interpreter, + web_search) can have well-defined schemas defined by the respective providers. + + This model is specified as part of semconv in `GenAI messages Python models - ServerToolCallPart + `__. + """ + + name: str + server_tool_call: Any + id: str | None = None + type: Literal["server_tool_call"] = "server_tool_call" + + +@dataclass() +class ServerToolCallResponse: + """Represents a server-side tool call response. + + Contains the outcome and details of a server tool execution. Provider-specific + tools (e.g., code_interpreter, web_search) can have well-defined response schemas + defined by the respective providers. + + This model is specified as part of semconv in `GenAI messages Python models - ServerToolCallResponsePart + `__. + """ + + server_tool_call_response: Any + id: str | None = None + type: Literal["server_tool_call_response"] = "server_tool_call_response" + + @dataclass() class Text: """Represents text content sent to or received from the model @@ -158,7 +207,16 @@ class GenericToolDefinition: ToolDefinition = Union[FunctionToolDefinition, GenericToolDefinition] MessagePart = Union[ - Text, ToolCall, ToolCallResponse, Blob, File, Uri, Reasoning, Any + Text, + ToolCallRequest, + ToolCallResponse, + ServerToolCall, + ServerToolCallResponse, + Blob, + File, + Uri, + Reasoning, + GenericPart, # For provider-specific types; prefer standard types above ] @@ -201,6 +259,7 @@ class GenAIInvocation: context_token: ContextToken | None = None span: Span | None = None attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) + error_type: str | None = None monotonic_start_s: float | None = None """ @@ -311,6 +370,51 @@ class EmbeddingInvocation(GenAIInvocation): """ +@dataclass() +class ToolCall(GenAIInvocation): + """Represents a tool call for execution tracking with spans and metrics. + + This type extends GenAIInvocation (like LLMInvocation) for consistent lifecycle + management across all invocation types. It is NOT used as a MessagePart directly - + use ToolCallRequest for that purpose. + + Inherits from GenAIInvocation: + - context_token: Context tracking for span lifecycle + - span: Active span reference + - attributes: Custom attributes dict for extensibility + + Reference: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md#execute-tool-span + + Semantic convention attributes for execute_tool spans: + - gen_ai.operation.name: "execute_tool" (Required) + - gen_ai.tool.name: Name of the tool (Recommended) + - gen_ai.tool.call.id: Tool call identifier (Recommended if available) + - gen_ai.tool.type: Type classification - "function", "extension", or "datastore" (Recommended if available) + - gen_ai.tool.description: Tool description (Recommended if available) + - gen_ai.tool.call.arguments: Parameters passed to tool (Opt-In, may contain sensitive data) + - gen_ai.tool.call.result: Result returned by tool (Opt-In, may contain sensitive data) + - error.type: Error type if operation failed (Conditionally Required) + """ + + # Message identification fields (same as ToolCallRequest) + # Note: These are required fields but must have defaults due to dataclass inheritance + name: str = "" + arguments: Any = None + id: str | None = None + type: Literal["tool_call"] = "tool_call" + + # Execution tracking fields (used for execute_tool spans): + # gen_ai.tool.type - Tool type: "function", "extension", or "datastore" + tool_type: str | None = None + # gen_ai.tool.description - Description of what the tool does + tool_description: str | None = None + # gen_ai.tool.call.result - Result returned by the tool (Opt-In, may contain sensitive data) + tool_result: Any = None + + # Timing field (not inherited from GenAIInvocation, matches LLMInvocation pattern) + monotonic_start_s: float | None = None + + @dataclass class Error: message: str diff --git a/util/opentelemetry-util-genai/tests/test_toolcall.py b/util/opentelemetry-util-genai/tests/test_toolcall.py new file mode 100644 index 00000000000..d076f5e72bc --- /dev/null +++ b/util/opentelemetry-util-genai/tests/test_toolcall.py @@ -0,0 +1,118 @@ +# 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. + +"""Tests for ToolCallRequest and ToolCall inheritance structure""" + +import pytest + +from opentelemetry.util.genai.types import ( + GenAIInvocation, + InputMessage, + ServerToolCall, + ServerToolCallResponse, + ToolCall, + ToolCallRequest, +) + + +def test_toolcallrequest_is_message_part(): + """ToolCallRequest is for message parts only""" + tcr = ToolCallRequest( + arguments={"location": "Paris"}, name="get_weather", id="call_123" + ) + msg = InputMessage(role="user", parts=[tcr]) + assert len(msg.parts) == 1 + + +def test_toolcall_inherits_from_genaiinvocation(): + """ToolCall inherits from GenAIInvocation for lifecycle management""" + tc = ToolCall(name="get_weather", arguments={"city": "Paris"}) + assert isinstance(tc, GenAIInvocation) + assert not isinstance(tc, ToolCallRequest) + + +def test_toolcall_has_attributes_dict(): + """ToolCall inherits attributes dict from GenAIInvocation""" + tc = ToolCall(name="test") + tc.attributes["custom.key"] = "value" + assert tc.attributes["custom.key"] == "value" + + +def test_toolcall_in_message_part_union(): + """ToolCall can be used in messages despite not inheriting from ToolCallRequest""" + tc = ToolCall(name="get_weather", arguments={"city": "Paris"}) + msg = InputMessage(role="assistant", parts=[tc]) + assert len(msg.parts) == 1 + assert isinstance(msg.parts[0], GenAIInvocation) + + +def test_server_tool_call_basic(): + """ServerToolCall can be created with required fields""" + stc = ServerToolCall( + name="code_interpreter", + server_tool_call={"type": "code_interpreter", "code": "print(1)"}, + ) + assert stc.name == "code_interpreter" + assert stc.server_tool_call == { + "type": "code_interpreter", + "code": "print(1)", + } + assert stc.id is None + assert stc.type == "server_tool_call" + + +def test_server_tool_call_with_id(): + """ServerToolCall can have an optional id""" + stc = ServerToolCall( + name="web_search", + server_tool_call={"type": "web_search", "query": "weather"}, + id="stc_001", + ) + assert stc.id == "stc_001" + + +def test_server_tool_call_response_basic(): + """ServerToolCallResponse can be created with required fields""" + stcr = ServerToolCallResponse( + server_tool_call_response={ + "type": "code_interpreter", + "output": "1\n", + }, + ) + assert stcr.server_tool_call_response == { + "type": "code_interpreter", + "output": "1\n", + } + assert stcr.id is None + assert stcr.type == "server_tool_call_response" + + +def test_server_tool_call_in_message(): + """ServerToolCall and ServerToolCallResponse work as MessageParts""" + stc = ServerToolCall( + name="code_interpreter", + server_tool_call={"type": "code_interpreter", "code": "x = 1"}, + ) + stcr = ServerToolCallResponse( + server_tool_call_response={"type": "code_interpreter", "output": ""}, + id="stc_001", + ) + msg = InputMessage(role="assistant", parts=[stc, stcr]) + assert len(msg.parts) == 2 + assert isinstance(msg.parts[0], ServerToolCall) + assert isinstance(msg.parts[1], ServerToolCallResponse) + + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) diff --git a/util/opentelemetry-util-genai/tests/test_upload.py b/util/opentelemetry-util-genai/tests/test_upload.py index dd87b971e09..aa5fcb5b4a1 100644 --- a/util/opentelemetry-util-genai/tests/test_upload.py +++ b/util/opentelemetry-util-genai/tests/test_upload.py @@ -44,7 +44,7 @@ types.InputMessage( role="assistant", parts=[ - types.ToolCall( + types.ToolCallRequest( id="get_capital_0", name="get_capital", arguments={"city": "Paris"}, From 828138a5a1f5e9eb0c3e70b6ef974943d48ac7f7 Mon Sep 17 00:00:00 2001 From: Ridhima Satam Date: Tue, 31 Mar 2026 11:14:31 -0700 Subject: [PATCH 40/78] Add support for workflow invocation in genAI utils handler (#4366) * Add support for workflow invocation in genAI utils handler * fix changelog * fixed errors * addressed comments * fixed precommit * made operation name immutable and added test * removed obsolete test * removed workflow specific method --- util/opentelemetry-util-genai/CHANGELOG.md | 3 + .../src/opentelemetry/util/genai/handler.py | 76 ++++- .../opentelemetry/util/genai/span_utils.py | 48 ++- .../src/opentelemetry/util/genai/types.py | 3 + .../tests/test_handler_workflow.py | 310 ++++++++++++++++++ .../tests/test_workflow_invocation.py | 4 - 6 files changed, 437 insertions(+), 7 deletions(-) create mode 100644 util/opentelemetry-util-genai/tests/test_handler_workflow.py diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index 565a18d5870..1a93525f691 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased + +- Add support for workflow in genAI utils handler. + ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4366](#4366)) - Enrich ToolCall type, breaking change: usage of ToolCall class renamed to ToolCallRequest ([#4218](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4218)) - Add EmbeddingInvocation span lifecycle support diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py index 80b801e9a1d..858e8a8237c 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py @@ -60,6 +60,7 @@ from __future__ import annotations +import logging import timeit from contextlib import contextmanager from typing import Iterator, TypeVar @@ -83,8 +84,10 @@ _apply_embedding_finish_attributes, _apply_error_attributes, _apply_llm_finish_attributes, + _apply_workflow_finish_attributes, _get_embedding_span_name, _get_llm_span_name, + _get_workflow_span_name, _maybe_emit_llm_event, ) from opentelemetry.util.genai.types import ( @@ -92,9 +95,27 @@ Error, GenAIInvocation, LLMInvocation, + WorkflowInvocation, ) from opentelemetry.util.genai.version import __version__ +_logger = logging.getLogger(__name__) + + +def _safe_detach(invocation: GenAIInvocation) -> None: + """Detach the context token if still present, as a safety net.""" + if invocation.context_token is not None: + try: + otel_context.detach(invocation.context_token) + except Exception: # pylint: disable=broad-except + pass + if invocation.span is not None: + try: + invocation.span.end() + except Exception: # pylint: disable=broad-except + pass + + _T = TypeVar("_T", bound=GenAIInvocation) @@ -160,13 +181,19 @@ def _start(self, invocation: _T) -> _T: """Start a GenAI invocation and create a pending span entry.""" if isinstance(invocation, LLMInvocation): span_name = _get_llm_span_name(invocation) + kind = SpanKind.CLIENT elif isinstance(invocation, EmbeddingInvocation): span_name = _get_embedding_span_name(invocation) + kind = SpanKind.CLIENT + elif isinstance(invocation, WorkflowInvocation): + span_name = _get_workflow_span_name(invocation) + kind = SpanKind.INTERNAL else: span_name = "" + kind = SpanKind.CLIENT span = self._tracer.start_span( name=span_name, - kind=SpanKind.CLIENT, + kind=kind, ) # Record a monotonic start timestamp (seconds) for duration # calculation using timeit.default_timer. @@ -192,6 +219,9 @@ def _stop(self, invocation: _T) -> _T: elif isinstance(invocation, EmbeddingInvocation): _apply_embedding_finish_attributes(span, invocation) self._record_embedding_metrics(invocation, span) + elif isinstance(invocation, WorkflowInvocation): + _apply_workflow_finish_attributes(span, invocation) + # TODO: Add workflow metrics when supported finally: # Detach context and end span even if finishing fails otel_context.detach(invocation.context_token) @@ -222,6 +252,10 @@ def _fail(self, invocation: _T, error: Error) -> _T: self._record_embedding_metrics( invocation, span, error_type=error_type ) + elif isinstance(invocation, WorkflowInvocation): + _apply_workflow_finish_attributes(span, invocation) + _apply_error_attributes(span, error, error_type) + # TODO: Add workflow metrics when supported finally: # Detach context and end span even if finishing fails otel_context.detach(invocation.context_token) @@ -304,6 +338,46 @@ def embedding( raise self.stop(invocation) + @contextmanager + def workflow( + self, invocation: WorkflowInvocation | None = None + ) -> Iterator[WorkflowInvocation]: + """Context manager for Workflow invocations. + + Only set data attributes on the invocation object, do not modify the span or context. + + Starts the span on entry. On normal exit, finalizes the invocation and ends the span. + If an exception occurs inside the context, marks the span as error, ends it, and + re-raises the original exception. + """ + if invocation is None: + invocation = WorkflowInvocation() + + try: + self.start(invocation) + except Exception: # pylint: disable=broad-except + _logger.warning( + "Failed to start workflow telemetry", exc_info=True + ) + + try: + yield invocation + except Exception as exc: + try: + self.fail(invocation, Error(message=str(exc), type=type(exc))) + except Exception: # pylint: disable=broad-except + _logger.warning( + "Failed to record workflow failure", exc_info=True + ) + _safe_detach(invocation) + raise + + try: + self.stop(invocation) + except Exception: # pylint: disable=broad-except + _logger.warning("Failed to stop workflow telemetry", exc_info=True) + _safe_detach(invocation) + def get_telemetry_handler( tracer_provider: TracerProvider | None = None, diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py index ac099e3dae6..0a82462c1bb 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py @@ -39,6 +39,7 @@ LLMInvocation, MessagePart, OutputMessage, + WorkflowInvocation, ) from opentelemetry.util.genai.utils import ( ContentCapturingMode, @@ -108,7 +109,14 @@ def _get_embedding_span_name(invocation: EmbeddingInvocation) -> str: return _get_span_name(invocation) -def _get_llm_messages_attributes_for_span( +def _get_workflow_span_name(invocation: WorkflowInvocation) -> str: + """Get the span name for an Workflow invocation.""" + operation_name = invocation.operation_name + name = invocation.name + return f"{operation_name} {name}" if name else operation_name + + +def _get_messages_attributes_for_span( input_messages: list[InputMessage], output_messages: list[OutputMessage], system_instruction: list[MessagePart] | None = None, @@ -240,7 +248,7 @@ def _apply_llm_finish_attributes( attributes.update(_get_llm_request_attributes(invocation)) attributes.update(_get_llm_response_attributes(invocation)) attributes.update( - _get_llm_messages_attributes_for_span( + _get_messages_attributes_for_span( invocation.input_messages, invocation.output_messages, invocation.system_instruction, @@ -345,6 +353,39 @@ def _get_llm_response_attributes( return {key: value for key, value in optional_attrs if value is not None} +def _apply_workflow_finish_attributes( + span: Span, invocation: WorkflowInvocation +) -> None: + """Apply attributes/messages common to finish() paths.""" + + # Build all attributes by reusing the attribute getter functions + attributes: dict[str, Any] = {} + attributes.update(_get_workflow_common_attributes(invocation)) + attributes.update( + _get_messages_attributes_for_span( + invocation.input_messages, + invocation.output_messages, + ) + ) + attributes.update(invocation.attributes) + + # Set all attributes on the span + if attributes: + span.set_attributes(attributes) + + +def _get_workflow_common_attributes( + invocation: WorkflowInvocation, +) -> dict[str, Any]: + """Get common Workflow attributes shared by finish() and error() paths. + + Returns a dictionary of attributes. + """ + return { + GenAI.GEN_AI_OPERATION_NAME: invocation.operation_name, + } + + def _get_embedding_response_attributes( invocation: EmbeddingInvocation, ) -> dict[str, Any]: @@ -365,9 +406,12 @@ def _get_embedding_response_attributes( "_get_llm_response_attributes", "_get_llm_span_name", "_maybe_emit_llm_event", + "_get_workflow_common_attributes", + "_apply_workflow_finish_attributes", "_apply_embedding_finish_attributes", "_get_embedding_common_attributes", "_get_embedding_request_attributes", "_get_embedding_response_attributes", "_get_embedding_span_name", + "_get_workflow_span_name", ] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py index 538d61490bf..6d59f03bf5e 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py @@ -285,6 +285,9 @@ class WorkflowInvocation(GenAIInvocation): default_factory=_new_output_messages ) + def __post_init__(self) -> None: + self.operation_name = "invoke_workflow" + @dataclass class LLMInvocation(GenAIInvocation): diff --git a/util/opentelemetry-util-genai/tests/test_handler_workflow.py b/util/opentelemetry-util-genai/tests/test_handler_workflow.py new file mode 100644 index 00000000000..d3af4e9ec75 --- /dev/null +++ b/util/opentelemetry-util-genai/tests/test_handler_workflow.py @@ -0,0 +1,310 @@ +from __future__ import annotations + +from unittest import TestCase +from unittest.mock import patch + +import pytest + +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.trace import SpanKind +from opentelemetry.trace.status import StatusCode +from opentelemetry.util.genai.handler import TelemetryHandler +from opentelemetry.util.genai.types import ( + Error, + InputMessage, + OutputMessage, + Text, + WorkflowInvocation, +) + + +class _WorkflowTestBase(TestCase): + """Shared setUp for workflow handler tests.""" + + def setUp(self) -> None: + self.span_exporter = InMemorySpanExporter() + self.tracer_provider = TracerProvider() + self.tracer_provider.add_span_processor( + SimpleSpanProcessor(self.span_exporter) + ) + self.handler = TelemetryHandler( + tracer_provider=self.tracer_provider, + ) + + def _get_finished_spans(self): + return self.span_exporter.get_finished_spans() + + +class TelemetryHandlerWorkflowTest(_WorkflowTestBase): + # ------------------------------------------------------------------ + # start_workflow + # ------------------------------------------------------------------ + + def test_operation_name_is_immutable(self) -> None: + invocation = WorkflowInvocation(name="wf", operation_name="custom_op") + self.assertEqual(invocation.operation_name, "invoke_workflow") + + def test_start_workflow_creates_span(self) -> None: + invocation = WorkflowInvocation(name="my_workflow") + self.handler.start(invocation) + + self.assertIsNotNone(invocation.span) + self.assertIsNotNone(invocation.context_token) + self.assertIsNotNone(invocation.monotonic_start_s) + + # Clean up + self.handler.stop(invocation) + + def test_start_workflow_span_name(self) -> None: + invocation = WorkflowInvocation(name="my_pipeline") + self.handler.start(invocation) + self.handler.stop(invocation) + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].name, "invoke_workflow my_pipeline") + + def test_start_workflow_span_name_without_name(self) -> None: + invocation = WorkflowInvocation() + self.handler.start(invocation) + self.handler.stop(invocation) + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].name, "invoke_workflow") + + def test_start_workflow_span_kind_is_internal(self) -> None: + invocation = WorkflowInvocation(name="wf") + self.handler.start(invocation) + self.handler.stop(invocation) + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].kind, SpanKind.INTERNAL) + + def test_start_workflow_records_monotonic_start(self) -> None: + invocation = WorkflowInvocation(name="wf") + with patch("timeit.default_timer", return_value=500.0): + self.handler.start(invocation) + self.assertEqual(invocation.monotonic_start_s, 500.0) + self.handler.stop(invocation) + + # ------------------------------------------------------------------ + # stop_workflow + # ------------------------------------------------------------------ + + def test_stop_workflow_ends_span(self) -> None: + invocation = WorkflowInvocation(name="wf") + self.handler.start(invocation) + self.handler.stop(invocation) + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + + def test_stop_workflow_sets_operation_name_attribute(self) -> None: + invocation = WorkflowInvocation(name="wf") + self.handler.start(invocation) + self.handler.stop(invocation) + + spans = self._get_finished_spans() + self.assertEqual( + spans[0].attributes[GenAI.GEN_AI_OPERATION_NAME], + "invoke_workflow", + ) + + def test_stop_workflow_sets_custom_attributes(self) -> None: + invocation = WorkflowInvocation(name="wf") + invocation.attributes["custom.key"] = "custom_value" + self.handler.start(invocation) + self.handler.stop(invocation) + + spans = self._get_finished_spans() + self.assertEqual(spans[0].attributes["custom.key"], "custom_value") + + def test_stop_workflow_noop_when_not_started(self) -> None: + invocation = WorkflowInvocation(name="wf") + # Not started — span and context_token are None + result = self.handler.stop(invocation) + self.assertIs(result, invocation) + self.assertEqual(len(self._get_finished_spans()), 0) + + def test_stop_workflow_returns_invocation(self) -> None: + invocation = WorkflowInvocation(name="wf") + self.handler.start(invocation) + result = self.handler.stop(invocation) + self.assertIs(result, invocation) + + # ------------------------------------------------------------------ + # fail_workflow + # ------------------------------------------------------------------ + + def test_fail_workflow_sets_error_status(self) -> None: + invocation = WorkflowInvocation(name="wf") + self.handler.start(invocation) + error = Error(message="something broke", type=RuntimeError) + self.handler.fail(invocation, error) + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].status.status_code, StatusCode.ERROR) + self.assertEqual(spans[0].status.description, "something broke") + + def test_fail_workflow_sets_error_type_attribute(self) -> None: + invocation = WorkflowInvocation(name="wf") + self.handler.start(invocation) + error = Error(message="bad", type=ValueError) + self.handler.fail(invocation, error) + + spans = self._get_finished_spans() + self.assertEqual(spans[0].attributes["error.type"], "ValueError") + + def test_fail_workflow_sets_operation_name_attribute(self) -> None: + invocation = WorkflowInvocation(name="wf") + self.handler.start(invocation) + error = Error(message="fail", type=TypeError) + self.handler.fail(invocation, error) + + spans = self._get_finished_spans() + self.assertEqual( + spans[0].attributes[GenAI.GEN_AI_OPERATION_NAME], + "invoke_workflow", + ) + + def test_fail_workflow_noop_when_not_started(self) -> None: + invocation = WorkflowInvocation(name="wf") + error = Error(message="fail", type=RuntimeError) + result = self.handler.fail(invocation, error) + self.assertIs(result, invocation) + self.assertEqual(len(self._get_finished_spans()), 0) + + def test_fail_workflow_returns_invocation(self) -> None: + invocation = WorkflowInvocation(name="wf") + self.handler.start(invocation) + error = Error(message="err", type=RuntimeError) + result = self.handler.fail(invocation, error) + self.assertIs(result, invocation) + + +class TelemetryHandlerWorkflowContextManagerTest(_WorkflowTestBase): + # ------------------------------------------------------------------ + # workflow context manager + # ------------------------------------------------------------------ + + def test_workflow_context_manager_creates_and_ends_span(self) -> None: + invocation = WorkflowInvocation(name="ctx_wf") + with self.handler.workflow(invocation) as inv: + self.assertIsNotNone(inv.span) + self.assertIsNotNone(inv.context_token) + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].name, "invoke_workflow ctx_wf") + + def test_workflow_context_manager_default_invocation(self) -> None: + with self.handler.workflow() as inv: + self.assertIsInstance(inv, WorkflowInvocation) + self.assertEqual(inv.name, "") + self.assertEqual(inv.operation_name, "invoke_workflow") + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + + def test_workflow_context_manager_sets_attributes_on_span(self) -> None: + invocation = WorkflowInvocation(name="wf") + with self.handler.workflow(invocation) as inv: + inv.attributes["my.attr"] = "hello" + + spans = self._get_finished_spans() + self.assertEqual(spans[0].attributes["my.attr"], "hello") + + def test_workflow_context_manager_reraises_exception(self) -> None: + invocation = WorkflowInvocation(name="wf") + with pytest.raises(ValueError, match="test error"): + with self.handler.workflow(invocation): + raise ValueError("test error") + + def test_workflow_context_manager_marks_error_on_exception(self) -> None: + invocation = WorkflowInvocation(name="wf") + with pytest.raises(ValueError): + with self.handler.workflow(invocation): + raise ValueError("boom") + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].status.status_code, StatusCode.ERROR) + self.assertEqual(spans[0].status.description, "boom") + self.assertEqual(spans[0].attributes["error.type"], "ValueError") + + def test_workflow_context_manager_success_has_unset_status(self) -> None: + invocation = WorkflowInvocation(name="wf") + with self.handler.workflow(invocation): + pass + + spans = self._get_finished_spans() + self.assertEqual(spans[0].status.status_code, StatusCode.UNSET) + + def test_workflow_context_manager_with_messages(self) -> None: + inp = InputMessage(role="user", parts=[Text(content="hello")]) + out = OutputMessage( + role="assistant", parts=[Text(content="hi")], finish_reason="stop" + ) + invocation = WorkflowInvocation( + name="msg_wf", + input_messages=[inp], + output_messages=[out], + ) + with self.handler.workflow(invocation): + pass + + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual( + spans[0].attributes[GenAI.GEN_AI_OPERATION_NAME], + "invoke_workflow", + ) + + def test_workflow_context_manager_swallows_start_failure(self) -> None: + """workflow() should yield even if start_workflow raises.""" + invocation = WorkflowInvocation(name="wf") + with patch.object( + self.handler, + "start", + side_effect=RuntimeError("start failed"), + ): + # Should not raise — the exception is swallowed with a warning + with self.handler.workflow(invocation) as inv: + self.assertIs(inv, invocation) + + def test_workflow_context_manager_swallows_stop_failure(self) -> None: + """workflow() should not raise if stop_workflow fails.""" + invocation = WorkflowInvocation(name="wf") + with patch.object( + self.handler, + "stop", + side_effect=RuntimeError("stop failed"), + ): + # Should not raise + with self.handler.workflow(invocation): + pass + + def test_workflow_context_manager_swallows_fail_workflow_failure( + self, + ) -> None: + """workflow() should still re-raise the original exception even if + fail_workflow itself raises.""" + invocation = WorkflowInvocation(name="wf") + with patch.object( + self.handler, + "fail", + side_effect=RuntimeError("fail broke"), + ): + with pytest.raises(ValueError, match="original"): + with self.handler.workflow(invocation): + raise ValueError("original") diff --git a/util/opentelemetry-util-genai/tests/test_workflow_invocation.py b/util/opentelemetry-util-genai/tests/test_workflow_invocation.py index c6f9bcdaecf..b9c0e756dac 100644 --- a/util/opentelemetry-util-genai/tests/test_workflow_invocation.py +++ b/util/opentelemetry-util-genai/tests/test_workflow_invocation.py @@ -21,10 +21,6 @@ def test_custom_name(self): invocation = WorkflowInvocation(name="customer_support_pipeline") assert invocation.name == "customer_support_pipeline" - def test_custom_operation_name(self): - invocation = WorkflowInvocation(operation_name="run_pipeline") - assert invocation.operation_name == "run_pipeline" - def test_with_input_messages(self): msg = InputMessage(role="user", parts=[Text(content="hello")]) invocation = WorkflowInvocation(input_messages=[msg]) From e1c8167e30f8d0ca7521b87ffe497063e45b6c6f Mon Sep 17 00:00:00 2001 From: Keith Decker <47755047+keith-decker@users.noreply.github.com> Date: Wed, 1 Apr 2026 06:45:35 -0600 Subject: [PATCH 41/78] GenAI Documentation Update (#4369) * update readme * Update util/opentelemetry-util-genai/README.rst Co-authored-by: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> * Update util/opentelemetry-util-genai/README.rst Co-authored-by: Liudmila Molkova --------- Co-authored-by: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Co-authored-by: Liudmila Molkova --- util/opentelemetry-util-genai/README.rst | 171 ++++++++++++++++------- 1 file changed, 123 insertions(+), 48 deletions(-) diff --git a/util/opentelemetry-util-genai/README.rst b/util/opentelemetry-util-genai/README.rst index 94806e01599..1394b8160ac 100644 --- a/util/opentelemetry-util-genai/README.rst +++ b/util/opentelemetry-util-genai/README.rst @@ -1,58 +1,129 @@ OpenTelemetry Util for GenAI ============================ +The GenAI Utils package provides boilerplate and helpers to standardize instrumentation for Generative AI. +It offers APIs to minimize the work needed to instrument GenAI libraries, +while providing standardization for generating spans, metrics, and events. -The GenAI Utils package will include boilerplate and helpers to standardize instrumentation for Generative AI. -This package will provide APIs and decorators to minimize the work needed to instrument genai libraries, -while providing standardization for generating both types of otel, "spans and metrics" and "spans, metrics and events" -This package relies on environment variables to configure capturing of message content. +Key Components +-------------- + +- ``TelemetryHandler`` -- manages LLM invocation lifecycles (spans, metrics, events) +- ``LLMInvocation`` and message types (``Text``, ``Reasoning``, ``Blob``, etc.) -- structured data model for GenAI interactions +- ``CompletionHook`` -- protocol for uploading content to external storage (built-in ``fsspec`` support) +- Metrics -- ``gen_ai.client.operation.duration`` and ``gen_ai.client.token.usage`` histograms + + +Usage +----- + +See the module docstring in ``opentelemetry.util.genai.handler`` for usage examples, +including context manager and manual lifecycle patterns. + + +Environment Variables +--------------------- + +This package relies on environment variables to configure capturing of message content. By default, message content will not be captured. -Set the environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` to `gen_ai_latest_experimental` to enable experimental features. -Set the environment variable `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` to one of: -- `NO_CONTENT`: Do not capture message content (default). -- `SPAN_ONLY`: Capture message content in spans only. -- `EVENT_ONLY`: Capture message content in events only. -- `SPAN_AND_EVENT`: Capture message content in both spans and events. - -To control event emission, you can optionally set `OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT` to `true` or `false` (case-insensitive). -This variable controls whether to emit `gen_ai.client.inference.operation.details` events. -If not explicitly set, the default value is automatically determined by `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT`: -- When `NO_CONTENT` or `SPAN_ONLY` is set: defaults to `false` -- When `EVENT_ONLY` or `SPAN_AND_EVENT` is set: defaults to `true` +Set the environment variable ``OTEL_SEMCONV_STABILITY_OPT_IN`` to ``gen_ai_latest_experimental`` to enable experimental features. +Set the environment variable ``OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT`` to one of: + +- ``NO_CONTENT``: Do not capture message content (default). +- ``SPAN_ONLY``: Capture message content in spans only. +- ``EVENT_ONLY``: Capture message content in events only. +- ``SPAN_AND_EVENT``: Capture message content in both spans and events. + +To control event emission, you can optionally set ``OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT`` to ``true`` or ``false`` (case-insensitive). +This variable controls whether to emit ``gen_ai.client.inference.operation.details`` events. +If not explicitly set, the default value is automatically determined by ``OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT``: + +- When ``NO_CONTENT`` or ``SPAN_ONLY`` is set: defaults to ``false`` +- When ``EVENT_ONLY`` or ``SPAN_AND_EVENT`` is set: defaults to ``true`` + If explicitly set, the user's value takes precedence over the default. -This package provides these span attributes: - -- `gen_ai.provider.name`: Str(openai) -- `gen_ai.operation.name`: Str(chat) -- `gen_ai.request.model`: Str(gpt-3.5-turbo) -- `gen_ai.response.finish_reasons`: Slice(["stop"]) -- `gen_ai.response.model`: Str(gpt-3.5-turbo-0125) -- `gen_ai.response.id`: Str(chatcmpl-Bz8yrvPnydD9pObv625n2CGBPHS13) -- `gen_ai.usage.input_tokens`: Int(24) -- `gen_ai.usage.output_tokens`: Int(7) -- `gen_ai.input.messages`: Str('[{"role": "Human", "parts": [{"content": "hello world", "type": "text"}]}]') -- `gen_ai.output.messages`: Str('[{"role": "AI", "parts": [{"content": "hello back", "type": "text"}], "finish_reason": "stop"}]') -- `gen_ai.system_instructions`: Str('[{"content": "You are a helpful assistant.", "type": "text"}]') (when system instruction is provided) - -This package also supports embedding invocation spans via the `embedding` context manager. -For embedding invocations, common attributes include: - -- `gen_ai.provider.name`: Str(openai) -- `gen_ai.operation.name`: Str(embeddings) -- `gen_ai.request.model`: Str(text-embedding-3-small) -- `gen_ai.embeddings.dimension.count`: Int(1536) -- `gen_ai.request.encoding_formats`: Slice(["float"]) -- `gen_ai.usage.input_tokens`: Int(24) -- `server.address`: Str(api.openai.com) -- `server.port`: Int(443) - -When `EVENT_ONLY` or `SPAN_AND_EVENT` mode is enabled and a LoggerProvider is configured, -the package also emits `gen_ai.client.inference.operation.details` events with structured -message content (as dictionaries instead of JSON strings). Note that when using `EVENT_ONLY` -or `SPAN_AND_EVENT`, the `OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT` environment variable defaults -to `true`, so events will be emitted automatically unless explicitly set to `false`. +When ``EVENT_ONLY`` or ``SPAN_AND_EVENT`` mode is enabled and a LoggerProvider is configured, +the package also emits ``gen_ai.client.inference.operation.details`` events with structured +message content (as dictionaries instead of JSON strings). Note that when using ``EVENT_ONLY`` +or ``SPAN_AND_EVENT``, the ``OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT`` environment variable defaults +to ``true``, so events will be emitted automatically unless explicitly set to ``false``. + +Completion Hook / Upload +^^^^^^^^^^^^^^^^^^^^^^^^ + +- ``OTEL_INSTRUMENTATION_GENAI_COMPLETION_HOOK``: Name of the completion hook entry point to load (e.g. ``upload``). +- ``OTEL_INSTRUMENTATION_GENAI_UPLOAD_BASE_PATH``: An ``fsspec``-compatible URI/path for uploading prompts and responses + (e.g. ``/path/to/prompts`` or ``gs://my_bucket``). Required when using the ``upload`` hook. +- ``OTEL_INSTRUMENTATION_GENAI_UPLOAD_FORMAT``: Format for uploaded data -- ``json`` (default) or ``jsonl``. +- ``OTEL_INSTRUMENTATION_GENAI_UPLOAD_MAX_QUEUE_SIZE``: Maximum number of concurrent uploads to queue (default: ``20``). + + +Span Attributes +--------------- + +This package sets the following span attributes on LLM invocations: + +**Common attributes:** + +- ``gen_ai.operation.name``: Str(chat) +- ``gen_ai.provider.name``: Str(openai) +- ``gen_ai.request.model``: Str(gpt-4o) +- ``server.address``: Str(api.openai.com) +- ``server.port``: Int(443) + +**Response attributes:** + +- ``gen_ai.response.finish_reasons``: Slice(["stop"]) +- ``gen_ai.response.model``: Str(gpt-4o-2024-05-13) +- ``gen_ai.response.id``: Str(chatcmpl-Bz8yrvPnydD9pObv625n2CGBPHS13) +- ``gen_ai.usage.input_tokens``: Int(24) +- ``gen_ai.usage.output_tokens``: Int(7) + +**Request parameter attributes (when provided):** + +- ``gen_ai.request.temperature``: Float(0.7) +- ``gen_ai.request.top_p``: Float(1.0) +- ``gen_ai.request.frequency_penalty``: Float(0.0) +- ``gen_ai.request.presence_penalty``: Float(0.0) +- ``gen_ai.request.max_tokens``: Int(1024) +- ``gen_ai.request.stop_sequences``: Slice(["\\n"]) +- ``gen_ai.request.seed``: Int(42) + +**Content attributes (sensitive, requires content capturing enabled):** + +- ``gen_ai.input.messages``: Str('[{"role": "user", "parts": [{"content": "hello world", "type": "text"}]}]') +- ``gen_ai.output.messages``: Str('[{"role": "assistant", "parts": [{"content": "hello back", "type": "text"}], "finish_reason": "stop"}]') +- ``gen_ai.system_instructions``: Str('[{"content": "You are a helpful assistant.", "type": "text"}]') + +**Error attributes:** + +- ``error.type``: Str(TimeoutError) + +Embedding Span Attributes +------------------------- + +This package also supports embedding invocation spans via the ``embedding`` context manager. +For embedding invocations, the following attributes are set: + +**Common attributes:** + +- ``gen_ai.operation.name``: Str(embeddings) +- ``gen_ai.provider.name``: Str(openai) +- ``server.address``: Str(api.openai.com) +- ``server.port``: Int(443) + +**Request attributes:** + +- ``gen_ai.request.model``: Str(text-embedding-3-small) +- ``gen_ai.embeddings.dimension.count``: Int(1536) +- ``gen_ai.request.encoding_formats``: Slice(["float"]) + +**Response attributes:** + +- ``gen_ai.response.model``: Str(text-embedding-3-small) +- ``gen_ai.usage.input_tokens``: Int(24) Installation @@ -62,11 +133,15 @@ Installation pip install opentelemetry-util-genai +For upload support (requires ``fsspec``):: + + pip install opentelemetry-util-genai[upload] + Design Document --------------- -The design document for the OpenTelemetry GenAI Utils can be found at: `Design Document `_ +The design document for the OpenTelemetry GenAI Utils can be found at: `Design Document `_ References ---------- From 8f31a0129c0a76f2c3359411af18224492908f77 Mon Sep 17 00:00:00 2001 From: "otelbot[bot]" <197425009+otelbot[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 13:11:13 +0000 Subject: [PATCH 42/78] Update opentelemetry-opamp-client version to v0.3b0 (#4382) Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- opamp/opentelemetry-opamp-client/CHANGELOG.md | 2 ++ .../src/opentelemetry/_opamp/version.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/opamp/opentelemetry-opamp-client/CHANGELOG.md b/opamp/opentelemetry-opamp-client/CHANGELOG.md index 60e9f9ebcda..d31499d2f46 100644 --- a/opamp/opentelemetry-opamp-client/CHANGELOG.md +++ b/opamp/opentelemetry-opamp-client/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## Version 0.2b0 (2026-04-01) + - Breaking change: callback class `Callbacks` renamed to `OpAMPCallbacks` ([#4355](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4355)) diff --git a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py index 29e61950cc7..32e2a06f96e 100644 --- a/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py +++ b/opamp/opentelemetry-opamp-client/src/opentelemetry/_opamp/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.2b0.dev" +__version__ = "0.3b0.dev" From 6bd19c066181ed5449794cd03984f7a4c81f2e35 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Date: Wed, 1 Apr 2026 08:18:46 -0700 Subject: [PATCH 43/78] fix: map Python CRITICAL log level to OTel FATAL severity text (#4365) * fix: map Python CRITICAL log level to OTel FATAL severity text in contrib handler The OTel specification defines the severity text for the highest severity range as "FATAL", but the contrib logging handler was passing through Python's native "CRITICAL" level name unchanged. This mirrors the fix made in open-telemetry/opentelemetry-python#5011 for the SDK handler. Related: open-telemetry/opentelemetry-python#4984 * Add CHANGELOG entry for CRITICAL -> FATAL severity text mapping * Update instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py --------- Co-authored-by: Leighton Chen Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 ++ .../opentelemetry/instrumentation/logging/handler.py | 12 ++++++++---- .../tests/test_handler.py | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c9c67be4bb..46f505e998d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4305](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4305)) - Don't import module in unwrap if not already imported ([#4321](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4321)) +- `opentelemetry-instrumentation-logging`: Map Python `CRITICAL` log level to OTel `FATAL` severity text and `WARNING` to `WARN` + ([#4365](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4365)) - `opentelemetry-instrumentation-logging`: Add recursion guard in LoggingHandler.emit to prevent deadlock ([#4302](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4302)) - `opentelemetry-instrumentation-grpc`: Fix bidirectional streaming RPCs raising `AttributeError: 'generator' object has no attribute 'add_done_callback'` diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py index aa8a319fd2a..44ba3164adf 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/handler.py @@ -188,10 +188,14 @@ def _translate(self, record: logging.LogRecord) -> LogRecord: else: body = record.getMessage() - # related to https://github.com/open-telemetry/opentelemetry-python/issues/3548 - # Severity Text = WARN as defined in https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#displaying-severity. - level_name = ( - "WARN" if record.levelname == "WARNING" else record.levelname + # 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_to_otel_severity_text = { + "WARNING": "WARN", + "CRITICAL": "FATAL", + } + level_name = _python_to_otel_severity_text.get( + record.levelname, record.levelname ) return LogRecord( diff --git a/instrumentation/opentelemetry-instrumentation-logging/tests/test_handler.py b/instrumentation/opentelemetry-instrumentation-logging/tests/test_handler.py index 68c8daaa249..0d15af33d4e 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/tests/test_handler.py +++ b/instrumentation/opentelemetry-instrumentation-logging/tests/test_handler.py @@ -357,7 +357,7 @@ def test_log_record_trace_correlation(self): record.log_record.body, "Critical message within span", ) - self.assertEqual(record.log_record.severity_text, "CRITICAL") + self.assertEqual(record.log_record.severity_text, "FATAL") self.assertEqual( record.log_record.severity_number, SeverityNumber.FATAL, @@ -390,7 +390,7 @@ def test_log_record_trace_correlation_deprecated(self): self.assertEqual( record.log_record.body, "Critical message within span" ) - self.assertEqual(record.log_record.severity_text, "CRITICAL") + self.assertEqual(record.log_record.severity_text, "FATAL") self.assertEqual( record.log_record.severity_number, SeverityNumber.FATAL ) From d22bf392b93825d6cde27444ff5a572af8fb00f5 Mon Sep 17 00:00:00 2001 From: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Date: Wed, 1 Apr 2026 09:02:46 -0700 Subject: [PATCH 44/78] DB and HTTP semantic convention stability migration for SQLAlchemy (#4110) * Add _semconv set_db fns * lint * Changelog * semconv opt-in for sqlalchemy instr * use imports not hardcode * Update comment on comment-in-attr * Add tests * Changelog * Add migration status * Sqlalchemy http,database opt-in * meter schema_url * Add sqlalchemy _get_db_name_from_cursor * Add per-signal semconv opt-in schema url precedence; add sqlalchemy usage * Update _get_db_name coverage * More db_name_from_cursor cases * split to lint * _get_schema parses url from semconv * _get_* from cursor or conn * Add _semconv set_db_operation, used by sqlalchemy * get_db_name safer, update docker-test * Fix test * Add schema_url asserts * Update CHANGELOG.md --------- Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 + instrumentation/README.md | 2 +- .../instrumentation/sqlalchemy/__init__.py | 31 +- .../instrumentation/sqlalchemy/engine.py | 204 ++++++-- .../instrumentation/sqlalchemy/package.py | 2 + .../tests/test_sqlalchemy.py | 435 ++++++++++++++++++ .../tests/test_sqlcommenter.py | 102 ++++ .../opentelemetry/instrumentation/_semconv.py | 78 +++- .../tests/test_semconv.py | 176 +++++++ 9 files changed, 988 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46f505e998d..257510fec09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4212](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4212)) - `opentelemetry-instrumentation-botocore`: Add support for instrumenting `aiobotocore` ([#4049](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4049)) +- `opentelemetry-instrumentation-sqlalchemy`: implement new semantic convention opt-in migration + ([#4110](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4110)) ### Fixed diff --git a/instrumentation/README.md b/instrumentation/README.md index 2802d8a872d..8d9a247945c 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -41,7 +41,7 @@ | [opentelemetry-instrumentation-redis](./opentelemetry-instrumentation-redis) | redis >= 2.6 | No | development | [opentelemetry-instrumentation-remoulade](./opentelemetry-instrumentation-remoulade) | remoulade >= 0.50 | No | development | [opentelemetry-instrumentation-requests](./opentelemetry-instrumentation-requests) | requests ~= 2.0 | Yes | migration -| [opentelemetry-instrumentation-sqlalchemy](./opentelemetry-instrumentation-sqlalchemy) | sqlalchemy >= 1.0.0, < 2.1.0 | Yes | development +| [opentelemetry-instrumentation-sqlalchemy](./opentelemetry-instrumentation-sqlalchemy) | sqlalchemy >= 1.0.0, < 2.1.0 | Yes | migration | [opentelemetry-instrumentation-sqlite3](./opentelemetry-instrumentation-sqlite3) | sqlite3 | No | development | [opentelemetry-instrumentation-starlette](./opentelemetry-instrumentation-starlette) | starlette >= 0.13 | Yes | development | [opentelemetry-instrumentation-system-metrics](./opentelemetry-instrumentation-system-metrics) | psutil >= 5 | No | development diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py index a95266351fb..dbcffc5ecf0 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py @@ -110,16 +110,16 @@ SQLComment in span attribute **************************** If sqlcommenter is enabled, you can opt into the inclusion of sqlcomment in -the query span ``db.statement`` attribute for your needs. If ``commenter_options`` -have been set, the span attribute comment will also be configured by this -setting. +the query span ``db.statement`` and/or ``db.query.text`` attribute for your +needs. If ``commenter_options`` have been set, the span attribute comment +will also be configured by this setting. .. code:: python from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor # Opts into sqlcomment for SQLAlchemy trace integration. - # Opts into sqlcomment for `db.statement` span attribute. + # Opts into sqlcomment for `db.statement` and/or `db.query.text` span attribute. SQLAlchemyInstrumentor().instrument( enable_commenter=True, commenter_options={}, @@ -127,7 +127,7 @@ ) Warning: - Capture of sqlcomment in ``db.statement`` may have high cardinality without platform normalization. See `Semantic Conventions for database spans `_ for more information. + Capture of sqlcomment in ``db.statement``/``db.query.text`` may have high cardinality without platform normalization. See `Semantic Conventions for database spans `_ for more information. API --- @@ -141,6 +141,11 @@ from sqlalchemy.engine.base import Engine from wrapt import wrap_function_wrapper as _w +from opentelemetry.instrumentation._semconv import ( + _get_schema_url_for_signal_types, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, +) from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.sqlalchemy.engine import ( EngineTracer, @@ -181,12 +186,24 @@ def _instrument(self, **kwargs): Returns: An instrumented engine if passed in as an argument or list of instrumented engines, None otherwise. """ + # Initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + + # Determine schema URL based on both DATABASE and HTTP signal types + # and semconv opt-in mode + schema_url = _get_schema_url_for_signal_types( + [ + _OpenTelemetryStabilitySignalType.DATABASE, + _OpenTelemetryStabilitySignalType.HTTP, + ] + ) + tracer_provider = kwargs.get("tracer_provider") tracer = get_tracer( __name__, __version__, tracer_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=schema_url, ) meter_provider = kwargs.get("meter_provider") @@ -194,7 +211,7 @@ def _instrument(self, **kwargs): __name__, __version__, meter_provider, - schema_url="https://opentelemetry.io/schemas/1.11.0", + schema_url=schema_url, ) connections_usage = meter.create_up_down_counter( diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py index 6a380a3221a..d357798ffab 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py @@ -22,26 +22,91 @@ ) from opentelemetry import trace +from opentelemetry.instrumentation._semconv import ( + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _set_db_name, + _set_db_operation, + _set_db_statement, + _set_db_system, + _set_db_user, + _set_http_net_peer_name_client, + _set_http_peer_port_client, +) from opentelemetry.instrumentation.sqlcommenter_utils import _add_sql_comment from opentelemetry.instrumentation.utils import ( _get_opentelemetry_values, is_instrumentation_enabled, ) -from opentelemetry.semconv._incubating.attributes.db_attributes import ( - DB_NAME, - DB_STATEMENT, - DB_SYSTEM, - DB_USER, -) from opentelemetry.semconv._incubating.attributes.net_attributes import ( - NET_PEER_NAME, - NET_PEER_PORT, NET_TRANSPORT, NetTransportValues, ) from opentelemetry.trace.status import Status, StatusCode +def _get_db_name_from_cursor_or_conn(vendor, conn, cursor): + """Return DB name from cursor or connection when available -- else None.""" + if not vendor: + return None + + vendor = vendor.lower() + db_name = None + if "postgres" in vendor: + info = getattr(getattr(cursor, "connection", None), "info", None) + if info and hasattr(info, "dbname"): + db_name = info.dbname + elif "mysql" in vendor: + db_name = _get_mysql_db_name(cursor) + elif "mssql" in vendor or "sqlserver" in vendor: + db_name = _get_mssql_db_name(cursor) + if not db_name: + engine = getattr(conn, "engine", None) + url = getattr(engine, "url", None) + db_name = getattr(url, "database", None) + else: + # Try connection for sqlite and others + engine = getattr(conn, "engine", None) + url = getattr(engine, "url", None) + db_name = getattr(url, "database", None) + return db_name + + +def _get_mysql_db_name(cursor): + """Extract database name from MySQL cursor.""" + # mysql-connector with c-extension uses _cnx + connection = getattr(cursor, "connection", None) or getattr( + cursor, "_cnx", None + ) + if not connection: + return None + if hasattr(connection, "database"): + return connection.database + if hasattr(connection, "db"): + raw_db_name = connection.db + return ( + raw_db_name.decode("utf-8") + if isinstance(raw_db_name, bytes) + else raw_db_name + ) + return None + + +def _get_mssql_db_name(cursor): + """Extract database name from MSSQL cursor.""" + connection = getattr(cursor, "connection", None) + if not connection: + return None + if hasattr(connection, "database"): + return connection.database + if hasattr(connection, "db"): + return connection.db + info = getattr(connection, "info", None) + if info and hasattr(info, "database"): + return info.database + return None + + def _normalize_vendor(vendor): """Return a canonical name for a type of database.""" if not vendor: @@ -119,13 +184,30 @@ def _wrap_connect_internal(func, module, args, kwargs): if not is_instrumentation_enabled(): return func(*args, **kwargs) + # Initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + sem_conv_opt_in_mode_db = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE, + ) + sem_conv_opt_in_mode_http = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + with tracer.start_as_current_span( "connect", kind=trace.SpanKind.CLIENT ) as span: if span.is_recording(): - attrs, _ = _get_attributes_from_url(module.url) + attrs, _ = _get_attributes_from_url( + module.url, + sem_conv_opt_in_mode_db, + sem_conv_opt_in_mode_http, + ) + _set_db_system( + attrs, + _normalize_vendor(module.name), + sem_conv_opt_in_mode_db, + ) span.set_attributes(attrs) - span.set_attribute(DB_SYSTEM, _normalize_vendor(module.name)) return func(*args, **kwargs) return _wrap_connect_internal @@ -143,6 +225,15 @@ def __init__( commenter_options=None, enable_attribute_commenter=False, ): + # Initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + self._sem_conv_opt_in_mode_db = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE, + ) + self._sem_conv_opt_in_mode_http = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + self.tracer = tracer self.connections_usage = connections_usage self.vendor = _normalize_vendor(engine.name) @@ -276,11 +367,19 @@ def _get_commenter_data(self, conn) -> dict: } return commenter_data - def _set_db_client_span_attributes(self, span, statement, attrs) -> None: - """Uses statement and attrs to set attributes of provided Otel span""" - span.set_attribute(DB_STATEMENT, statement) - span.set_attribute(DB_SYSTEM, self.vendor) - for key, value in attrs.items(): + def _set_db_client_span_attributes( + self, span, statement, db_name, attrs + ) -> None: + """Uses statement, db_name, and attrs to set attributes of provided Otel span""" + span_attrs = dict(attrs) + _set_db_statement(span_attrs, statement, self._sem_conv_opt_in_mode_db) + _set_db_system(span_attrs, self.vendor, self._sem_conv_opt_in_mode_db) + _set_db_operation( + span_attrs, + self._operation_name(db_name, statement), + self._sem_conv_opt_in_mode_db, + ) + for key, value in span_attrs.items(): span.set_attribute(key, value) def _before_cur_exec( @@ -289,11 +388,24 @@ def _before_cur_exec( if not is_instrumentation_enabled(): return statement, params - attrs, found = _get_attributes_from_url(conn.engine.url) + attrs, found = _get_attributes_from_url( + conn.engine.url, + self._sem_conv_opt_in_mode_db, + self._sem_conv_opt_in_mode_http, + ) if not found: - attrs = _get_attributes_from_cursor(self.vendor, cursor, attrs) + attrs = _get_attributes_from_cursor_or_conn( + self.vendor, + conn, + cursor, + attrs, + self._sem_conv_opt_in_mode_db, + self._sem_conv_opt_in_mode_http, + ) + + # Extract db_name for operation name + db_name = _get_db_name_from_cursor_or_conn(self.vendor, conn, cursor) - db_name = attrs.get(DB_NAME, "") span = self.tracer.start_span( self._operation_name(db_name, statement), kind=trace.SpanKind.CLIENT, @@ -307,19 +419,19 @@ def _before_cur_exec( # just to handle type safety statement = str(statement) - # sqlcomment is added to executed query and db.statement span attribute + # sqlcomment is added to executed query and db.statement and/or db.query.text span attribute statement = _add_sql_comment( statement, **commenter_data ) self._set_db_client_span_attributes( - span, statement, attrs + span, statement, db_name, attrs ) else: # sqlcomment is only added to executed query - # so db.statement is set before add_sql_comment + # so db.statement and/or db.query.text is set before add_sql_comment self._set_db_client_span_attributes( - span, statement, attrs + span, statement, db_name, attrs ) statement = _add_sql_comment( statement, **commenter_data @@ -327,7 +439,9 @@ def _before_cur_exec( else: # no sqlcomment anywhere - self._set_db_client_span_attributes(span, statement, attrs) + self._set_db_client_span_attributes( + span, statement, db_name, attrs + ) context._otel_span = span @@ -358,42 +472,64 @@ def _handle_error(context): span.end() -def _get_attributes_from_url(url): +def _get_attributes_from_url( + url, sem_conv_opt_in_mode_db, sem_conv_opt_in_mode_http +): """Set connection tags from the url. return true if successful.""" attrs = {} if url.host: - attrs[NET_PEER_NAME] = url.host + _set_http_net_peer_name_client( + attrs, url.host, sem_conv_opt_in_mode_http + ) if url.port: - attrs[NET_PEER_PORT] = url.port + _set_http_peer_port_client(attrs, url.port, sem_conv_opt_in_mode_http) if url.database: - attrs[DB_NAME] = url.database + _set_db_name(attrs, url.database, sem_conv_opt_in_mode_db) if url.username: - attrs[DB_USER] = url.username + _set_db_user(attrs, url.username, sem_conv_opt_in_mode_db) return attrs, bool(url.host) -def _get_attributes_from_cursor(vendor, cursor, attrs): +def _get_attributes_from_cursor_or_conn( + vendor, + conn, + cursor, + attrs, + sem_conv_opt_in_mode_db, + sem_conv_opt_in_mode_http, +): """Attempt to set db connection attributes by introspecting the cursor.""" if vendor == "postgresql": info = getattr(getattr(cursor, "connection", None), "info", None) if not info: return attrs - attrs[DB_NAME] = info.dbname + db_name = _get_db_name_from_cursor_or_conn(vendor, conn, cursor) + _set_db_name(attrs, db_name, sem_conv_opt_in_mode_db) is_unix_socket = info.host and info.host.startswith("/") if is_unix_socket: attrs[NET_TRANSPORT] = NetTransportValues.OTHER.value if info.port: # postgresql enforces this pattern on all socket names - attrs[NET_PEER_NAME] = os.path.join( - info.host, f".s.PGSQL.{info.port}" + _set_http_net_peer_name_client( + attrs, + os.path.join(info.host, f".s.PGSQL.{info.port}"), + sem_conv_opt_in_mode_http, ) else: attrs[NET_TRANSPORT] = NetTransportValues.IP_TCP.value - attrs[NET_PEER_NAME] = info.host + _set_http_net_peer_name_client( + attrs, info.host, sem_conv_opt_in_mode_http + ) if info.port: - attrs[NET_PEER_PORT] = int(info.port) + _set_http_peer_port_client( + attrs, int(info.port), sem_conv_opt_in_mode_http + ) + elif vendor == "sqlite": + db_name = _get_db_name_from_cursor_or_conn(vendor, conn, cursor) + _set_db_name(attrs, db_name, sem_conv_opt_in_mode_db) + # SQLite has no network attributes return attrs diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/package.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/package.py index 77b148e51c5..a95b8a6c767 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/package.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/package.py @@ -15,3 +15,5 @@ _instruments = ("sqlalchemy >= 1.0.0, < 2.1.0",) _supports_metrics = True + +_semconv_status = "migration" diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py index 882659daf7a..36257d9d32d 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py @@ -23,18 +23,35 @@ ) from opentelemetry import trace +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.sqlalchemy import ( EngineTracer, SQLAlchemyInstrumentor, ) +from opentelemetry.instrumentation.sqlalchemy.engine import ( + _get_db_name_from_cursor_or_conn, +) from opentelemetry.instrumentation.utils import suppress_instrumentation from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider, export from opentelemetry.semconv._incubating.attributes.db_attributes import ( DB_NAME, + DB_OPERATION, DB_STATEMENT, DB_SYSTEM, ) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, +) +from opentelemetry.semconv.attributes.db_attributes import ( + DB_NAMESPACE, + DB_OPERATION_NAME, + DB_QUERY_TEXT, + DB_SYSTEM_NAME, +) from opentelemetry.test.test_base import TestBase @@ -43,6 +60,12 @@ class TestSqlalchemyInstrumentation(TestBase): def inject_fixtures(self, caplog): self.caplog = caplog # pylint: disable=attribute-defined-outside-init + def setUp(self): + super().setUp() + # Reset semconv state before each test for reproducibility + # Tests using @mock.patch.dict will re-initialize again after the mock is applied + _OpenTelemetrySemanticConventionStability._initialized = False + def tearDown(self): super().tearDown() SQLAlchemyInstrumentor().uninstrument() @@ -687,6 +710,276 @@ def test_suppress_instrumentation_connect(self): spans_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans_list), 0) + def test_semconv_default_mode(self): + SQLAlchemyInstrumentor().uninstrument() + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + + connect_span = spans[0] + self.assertEqual( + connect_span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/1.11.0", + ) + self.assertIn(DB_SYSTEM, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM], "sqlite") + self.assertIn(DB_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAME], ":memory:") + # Verify new conventions are NOT present + self.assertNotIn(DB_SYSTEM_NAME, connect_span.attributes) + self.assertNotIn(DB_NAMESPACE, connect_span.attributes) + + query_span = spans[1] + self.assertIn(DB_STATEMENT, query_span.attributes) + self.assertIn(DB_SYSTEM, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM], "sqlite") + self.assertIn(DB_OPERATION, query_span.attributes) + self.assertEqual( + query_span.attributes[DB_OPERATION], "SELECT :memory:" + ) + # Verify new conventions are NOT present + self.assertNotIn(DB_QUERY_TEXT, query_span.attributes) + self.assertNotIn(DB_SYSTEM_NAME, query_span.attributes) + + @mock.patch.dict("os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "http"}) + def test_semconv_http_mode(self): + SQLAlchemyInstrumentor().uninstrument() + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + + connect_span = spans[0] + self.assertEqual( + connect_span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/1.21.0", + ) + # HTTP attributes should use new semconv + self.assertNotIn(NET_PEER_NAME, connect_span.attributes) + # DB attributes should still use old semconv + self.assertIn(DB_SYSTEM, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM], "sqlite") + self.assertIn(DB_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAME], ":memory:") + # Verify new DB conventions are NOT present + self.assertNotIn(DB_SYSTEM_NAME, connect_span.attributes) + self.assertNotIn(DB_NAMESPACE, connect_span.attributes) + + query_span = spans[1] + # DB attributes should still use old semconv + self.assertIn(DB_STATEMENT, query_span.attributes) + self.assertIn(DB_SYSTEM, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM], "sqlite") + # Verify new DB conventions are NOT present + self.assertNotIn(DB_QUERY_TEXT, query_span.attributes) + self.assertNotIn(DB_SYSTEM_NAME, query_span.attributes) + + @mock.patch.dict("os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "database"}) + def test_semconv_database_mode(self): + SQLAlchemyInstrumentor().uninstrument() + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + + connect_span = spans[0] + self.assertEqual( + connect_span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/1.25.0", + ) + self.assertIn(DB_SYSTEM_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM_NAME], "sqlite") + self.assertIn(DB_NAMESPACE, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAMESPACE], ":memory:") + # Verify old conventions are NOT present + self.assertNotIn(DB_SYSTEM, connect_span.attributes) + self.assertNotIn(DB_NAME, connect_span.attributes) + + query_span = spans[1] + self.assertIn(DB_QUERY_TEXT, query_span.attributes) + self.assertIn(DB_SYSTEM_NAME, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM_NAME], "sqlite") + self.assertIn(DB_OPERATION_NAME, query_span.attributes) + self.assertEqual( + query_span.attributes[DB_OPERATION_NAME], "SELECT :memory:" + ) + # Verify old conventions are NOT present + self.assertNotIn(DB_STATEMENT, query_span.attributes) + self.assertNotIn(DB_SYSTEM, query_span.attributes) + + @mock.patch.dict( + "os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "http,database"} + ) + def test_semconv_http_and_database_mode(self): + SQLAlchemyInstrumentor().uninstrument() + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + + connect_span = spans[0] + self.assertEqual( + connect_span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/1.25.0", + ) + # New DB conventions should be present + self.assertIn(DB_SYSTEM_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM_NAME], "sqlite") + self.assertIn(DB_NAMESPACE, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAMESPACE], ":memory:") + # Old DB conventions should NOT be present + self.assertNotIn(DB_SYSTEM, connect_span.attributes) + self.assertNotIn(DB_NAME, connect_span.attributes) + + query_span = spans[1] + # New DB conventions should be present + self.assertIn(DB_QUERY_TEXT, query_span.attributes) + self.assertIn(DB_SYSTEM_NAME, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM_NAME], "sqlite") + # Old DB conventions should NOT be present + self.assertNotIn(DB_STATEMENT, query_span.attributes) + self.assertNotIn(DB_SYSTEM, query_span.attributes) + + @mock.patch.dict("os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "http/dup"}) + def test_semconv_http_dup_mode(self): + SQLAlchemyInstrumentor().uninstrument() + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + + connect_span = spans[0] + self.assertEqual( + connect_span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/1.21.0", + ) + # DB attributes should use old semconv only + self.assertIn(DB_SYSTEM, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM], "sqlite") + self.assertIn(DB_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAME], ":memory:") + # Verify new DB conventions are NOT present + self.assertNotIn(DB_SYSTEM_NAME, connect_span.attributes) + self.assertNotIn(DB_NAMESPACE, connect_span.attributes) + + query_span = spans[1] + # DB attributes should use old semconv + self.assertIn(DB_STATEMENT, query_span.attributes) + self.assertIn(DB_SYSTEM, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM], "sqlite") + # Verify new DB conventions are NOT present + self.assertNotIn(DB_QUERY_TEXT, query_span.attributes) + self.assertNotIn(DB_SYSTEM_NAME, query_span.attributes) + + @mock.patch.dict( + "os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "database/dup"} + ) + def test_semconv_database_dup_mode(self): + SQLAlchemyInstrumentor().uninstrument() + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + + connect_span = spans[0] + self.assertEqual( + connect_span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/1.25.0", + ) + # Old conventions + self.assertIn(DB_SYSTEM, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM], "sqlite") + self.assertIn(DB_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAME], ":memory:") + # New conventions + self.assertIn(DB_SYSTEM_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM_NAME], "sqlite") + self.assertIn(DB_NAMESPACE, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAMESPACE], ":memory:") + + query_span = spans[1] + # Old conventions + self.assertIn(DB_STATEMENT, query_span.attributes) + self.assertIn(DB_SYSTEM, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM], "sqlite") + # New conventions + self.assertIn(DB_QUERY_TEXT, query_span.attributes) + self.assertIn(DB_SYSTEM_NAME, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM_NAME], "sqlite") + + @mock.patch.dict( + "os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "http/dup,database/dup"} + ) + def test_semconv_http_and_database_dup_mode(self): + SQLAlchemyInstrumentor().uninstrument() + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1 + 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + + connect_span = spans[0] + self.assertEqual( + connect_span.instrumentation_scope.schema_url, + "https://opentelemetry.io/schemas/1.25.0", + ) + # Both old and new DB conventions + self.assertIn(DB_SYSTEM, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM], "sqlite") + self.assertIn(DB_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAME], ":memory:") + self.assertIn(DB_SYSTEM_NAME, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_SYSTEM_NAME], "sqlite") + self.assertIn(DB_NAMESPACE, connect_span.attributes) + self.assertEqual(connect_span.attributes[DB_NAMESPACE], ":memory:") + + query_span = spans[1] + # Both old and new DB conventions + self.assertIn(DB_STATEMENT, query_span.attributes) + self.assertIn(DB_SYSTEM, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM], "sqlite") + self.assertIn(DB_QUERY_TEXT, query_span.attributes) + self.assertIn(DB_SYSTEM_NAME, query_span.attributes) + self.assertEqual(query_span.attributes[DB_SYSTEM_NAME], "sqlite") + def test_suppress_instrumentation_cursor_and_metric(self): engine = create_engine("sqlite:///:memory:") SQLAlchemyInstrumentor().instrument( @@ -704,3 +997,145 @@ def test_suppress_instrumentation_cursor_and_metric(self): metric_list = self.get_sorted_metrics() self.assertEqual(len(metric_list), 0) + + def test_get_db_name_from_cursor_or_conn_postgresql_success(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_info = mock.Mock() + mock_info.dbname = "test_database" + mock_connection.info = mock_info + mock_cursor.connection = mock_connection + result = _get_db_name_from_cursor_or_conn( + "postgresql", mock_connection, mock_cursor + ) + self.assertEqual(result, "test_database") + + def test_get_db_name_from_cursor_or_conn_postgresql_no_connection(self): + mock_cursor = mock.Mock() + mock_cursor.connection = None + mock_connection = mock.Mock() + result = _get_db_name_from_cursor_or_conn( + "postgresql", mock_connection, mock_cursor + ) + self.assertIsNone(result) + + def test_get_db_name_from_cursor_or_conn_postgresql_no_dbname(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_info = mock.Mock() + mock_info.dbname = None + mock_connection.info = mock_info + mock_cursor.connection = mock_connection + result = _get_db_name_from_cursor_or_conn( + "postgresql", mock_connection, mock_cursor + ) + self.assertIsNone(result) + + def test_get_db_name_from_cursor_or_conn_unknown_vendor_with_url(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_connection.engine.url.database = "foo" + mock_cursor.connection = mock_connection + result = _get_db_name_from_cursor_or_conn( + "unknown_db", mock_connection, mock_cursor + ) + self.assertEqual(result, "foo") + + def test_get_db_name_from_cursor_or_conn_unknown_vendor_without_url(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_connection.engine.url.database = None + mock_cursor.connection = mock_connection + result = _get_db_name_from_cursor_or_conn( + "unknown_db", mock_connection, mock_cursor + ) + self.assertIsNone(result) + + def test_get_db_name_from_cursor_or_conn_mysql_with_database_attr(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_connection.database = "mysql_test_db" + mock_cursor.connection = mock_connection + result = _get_db_name_from_cursor_or_conn( + "mysql", mock_connection, mock_cursor + ) + self.assertEqual(result, "mysql_test_db") + + def test_get_db_name_from_cursor_or_conn_mysql_with_db_attr_string(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_connection.db = "mysql_test_db" + del mock_connection.database # Remove database attribute + mock_cursor.connection = mock_connection + result = _get_db_name_from_cursor_or_conn( + "mysql", mock_connection, mock_cursor + ) + self.assertEqual(result, "mysql_test_db") + + def test_get_db_name_from_cursor_or_conn_mysql_with_db_attr_bytes(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_connection.db = b"mysql_test_db" + del mock_connection.database # Remove database attribute + mock_cursor.connection = mock_connection + result = _get_db_name_from_cursor_or_conn( + "mysql", mock_connection, mock_cursor + ) + self.assertEqual(result, "mysql_test_db") + + def test_get_db_name_from_cursor_or_conn_mysql_with_cnx_attr(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_cnx = mock.Mock() + mock_cnx.database = "mysql_cnx_db" + mock_cursor.connection = None + mock_cursor._cnx = mock_cnx + result = _get_db_name_from_cursor_or_conn( + "mysql", mock_connection, mock_cursor + ) + self.assertEqual(result, "mysql_cnx_db") + + def test_get_db_name_from_cursor_or_conn_mssql_with_database_attr(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_connection.database = "mssql_test_db" + mock_cursor.connection = mock_connection + result = _get_db_name_from_cursor_or_conn( + "mssql", mock_connection, mock_cursor + ) + self.assertEqual(result, "mssql_test_db") + + def test_get_db_name_from_cursor_or_conn_mysql_variant_names(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_connection.database = "test_db" + mock_cursor.connection = mock_connection + for vendor in ["mysql", "pymysql", "mysqlclient", "mysql+pymysql"]: + result = _get_db_name_from_cursor_or_conn( + vendor, mock_connection, mock_cursor + ) + self.assertEqual(result, "test_db", f"Failed for vendor: {vendor}") + + def test_get_db_name_from_cursor_or_conn_mssql_variant_names(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_connection.database = "test_db" + mock_cursor.connection = mock_connection + for vendor in ["mssql", "mssql+pyodbc", "sqlserver"]: + result = _get_db_name_from_cursor_or_conn( + vendor, mock_connection, mock_cursor + ) + self.assertEqual(result, "test_db", f"Failed for vendor: {vendor}") + + def test_get_db_name_from_cursor_or_conn_postgresql_variant_names(self): + mock_cursor = mock.Mock() + mock_connection = mock.Mock() + mock_info = mock.Mock() + mock_info.dbname = "test_db" + mock_connection.info = mock_info + mock_cursor.connection = mock_connection + for vendor in ["postgresql", "postgres", "postgresql+psycopg2"]: + result = _get_db_name_from_cursor_or_conn( + vendor, mock_connection, mock_cursor + ) + self.assertEqual(result, "test_db", f"Failed for vendor: {vendor}") diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py index 946be53b3ca..aeb9f740814 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py @@ -13,6 +13,7 @@ # limitations under the License. import logging import re +from unittest import mock import pytest from sqlalchemy import ( @@ -21,10 +22,17 @@ ) from opentelemetry import context +from opentelemetry.instrumentation._semconv import ( + OTEL_SEMCONV_STABILITY_OPT_IN, + _OpenTelemetrySemanticConventionStability, +) from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor from opentelemetry.semconv._incubating.attributes.db_attributes import ( DB_STATEMENT, ) +from opentelemetry.semconv.attributes.db_attributes import ( + DB_QUERY_TEXT, +) from opentelemetry.test.test_base import TestBase @@ -33,6 +41,10 @@ class TestSqlalchemyInstrumentationWithSQLCommenter(TestBase): def inject_fixtures(self, caplog): self.caplog = caplog # pylint: disable=attribute-defined-outside-init + def setUp(self): + super().setUp() + _OpenTelemetrySemanticConventionStability._initialized = False + def tearDown(self): super().tearDown() SQLAlchemyInstrumentor().uninstrument() @@ -358,6 +370,96 @@ def test_sqlcommenter_enabled_stmt_enabled_create_engine_after_instrumentation( r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", ) + @mock.patch.dict("os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "database"}) + def test_sqlcommenter_enabled_database_mode(self): + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + enable_commenter=True, + commenter_options={"db_framework": False}, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + # Query log should have sqlcommenter + self.assertRegex( + self.caplog.records[-2].getMessage(), + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + query_span = spans[1] + # Should use new semconv attribute (db.query.text not db.statement) + self.assertNotIn(DB_STATEMENT, query_span.attributes) + self.assertIn(DB_QUERY_TEXT, query_span.attributes) + self.assertEqual(query_span.attributes[DB_QUERY_TEXT], "SELECT 1;") + + @mock.patch.dict("os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "database"}) + def test_sqlcommenter_enabled_stmt_enabled_database_mode(self): + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + enable_commenter=True, + commenter_options={"db_framework": False}, + enable_attribute_commenter=True, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + query_log = self.caplog.records[-2].getMessage() + self.assertRegex( + query_log, + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + query_span = spans[1] + # Should use new semconv attribute with comment + self.assertNotIn(DB_STATEMENT, query_span.attributes) + self.assertIn(DB_QUERY_TEXT, query_span.attributes) + self.assertRegex( + query_span.attributes[DB_QUERY_TEXT], + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + + @mock.patch.dict( + "os.environ", {OTEL_SEMCONV_STABILITY_OPT_IN: "database/dup"} + ) + def test_sqlcommenter_enabled_database_dup_mode(self): + _OpenTelemetrySemanticConventionStability._initialized = False + _OpenTelemetrySemanticConventionStability._initialize() + logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + engine = create_engine("sqlite:///:memory:") + SQLAlchemyInstrumentor().instrument( + engine=engine, + tracer_provider=self.tracer_provider, + enable_commenter=True, + commenter_options={"db_framework": False}, + enable_attribute_commenter=True, + ) + cnx = engine.connect() + cnx.execute(text("SELECT 1;")).fetchall() + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 2) + query_span = spans[1] + # Should have both old and new semconv attributes with comment + self.assertIn(DB_STATEMENT, query_span.attributes) + self.assertRegex( + query_span.attributes[DB_STATEMENT], + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + self.assertIn(DB_QUERY_TEXT, query_span.attributes) + self.assertRegex( + query_span.attributes[DB_QUERY_TEXT], + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + ) + def test_sqlcommenter_disabled_create_engine_after_instrumentation(self): SQLAlchemyInstrumentor().instrument( tracer_provider=self.tracer_provider, diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index ccf1f392025..1edd18d0385 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -18,10 +18,14 @@ import threading from enum import Enum from typing import Container, Mapping, MutableMapping +from urllib.parse import urlparse + +from packaging import version as package_version from opentelemetry.instrumentation.utils import http_status_to_status_code from opentelemetry.semconv._incubating.attributes.db_attributes import ( DB_NAME, + DB_OPERATION, DB_STATEMENT, DB_SYSTEM, DB_USER, @@ -50,6 +54,7 @@ ) from opentelemetry.semconv.attributes.db_attributes import ( DB_NAMESPACE, + DB_OPERATION_NAME, DB_QUERY_TEXT, DB_SYSTEM_NAME, ) @@ -177,6 +182,9 @@ 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" @@ -590,6 +598,17 @@ def _set_db_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) + + # General @@ -634,8 +653,63 @@ def _set_status( span.set_status(Status(status)) -# Get schema version based off of opt-in mode 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 "https://opentelemetry.io/schemas/1.11.0" + 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/opentelemetry-instrumentation/tests/test_semconv.py b/opentelemetry-instrumentation/tests/test_semconv.py index 4560e281019..f160c512862 100644 --- a/opentelemetry-instrumentation/tests/test_semconv.py +++ b/opentelemetry-instrumentation/tests/test_semconv.py @@ -17,10 +17,14 @@ from unittest.mock import Mock, patch from opentelemetry.instrumentation._semconv import ( + _LEGACY_SCHEMA_VERSION, OTEL_SEMCONV_STABILITY_OPT_IN, + _get_schema_url_for_signal_types, + _get_schema_version_for_opt_in_mode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _set_db_name, + _set_db_operation, _set_db_statement, _set_db_system, _set_db_user, @@ -29,12 +33,14 @@ ) from opentelemetry.semconv._incubating.attributes.db_attributes import ( DB_NAME, + DB_OPERATION, DB_STATEMENT, DB_SYSTEM, DB_USER, ) from opentelemetry.semconv.attributes.db_attributes import ( DB_NAMESPACE, + DB_OPERATION_NAME, DB_QUERY_TEXT, DB_SYSTEM_NAME, ) @@ -188,6 +194,134 @@ def test_stability_mode_dup_precedence(self): ) +class TestOpenTelemetrySemConvSchemaUrl(TestCase): + @stability_mode("") + def test_get_schema_version_for_opt_in_mode_default(self): + version = _get_schema_version_for_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, _StabilityMode.DEFAULT + ) + self.assertEqual(version, _LEGACY_SCHEMA_VERSION) + + version = _get_schema_version_for_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE, _StabilityMode.DEFAULT + ) + self.assertEqual(version, _LEGACY_SCHEMA_VERSION) + + version = _get_schema_version_for_opt_in_mode( + _OpenTelemetryStabilitySignalType.GEN_AI, _StabilityMode.DEFAULT + ) + self.assertEqual(version, _LEGACY_SCHEMA_VERSION) + + @stability_mode("") + def test_get_schema_version_for_opt_in_mode_http_stable(self): + version = _get_schema_version_for_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, _StabilityMode.HTTP + ) + self.assertEqual(version, "1.21.0") + + @stability_mode("") + def test_get_schema_version_for_opt_in_mode_database_stable(self): + version = _get_schema_version_for_opt_in_mode( + _OpenTelemetryStabilitySignalType.DATABASE, _StabilityMode.DATABASE + ) + self.assertEqual(version, "1.25.0") + + @stability_mode("") + def test_get_schema_version_for_opt_in_mode_gen_ai_stable(self): + version = _get_schema_version_for_opt_in_mode( + _OpenTelemetryStabilitySignalType.GEN_AI, + _StabilityMode.GEN_AI_LATEST_EXPERIMENTAL, + ) + self.assertEqual(version, "1.26.0") + + @stability_mode("") + def test_get_schema_url_for_signal_types_single_http_default(self): + url = _get_schema_url_for_signal_types( + [_OpenTelemetryStabilitySignalType.HTTP] + ) + self.assertEqual( + url, f"https://opentelemetry.io/schemas/{_LEGACY_SCHEMA_VERSION}" + ) + + @stability_mode("http") + def test_get_schema_url_for_signal_types_single_http_stable(self): + url = _get_schema_url_for_signal_types( + [_OpenTelemetryStabilitySignalType.HTTP] + ) + self.assertEqual(url, "https://opentelemetry.io/schemas/1.21.0") + + @stability_mode("database") + def test_get_schema_url_for_signal_types_single_database_stable(self): + url = _get_schema_url_for_signal_types( + [_OpenTelemetryStabilitySignalType.DATABASE] + ) + self.assertEqual(url, "https://opentelemetry.io/schemas/1.25.0") + + @stability_mode("http,database") + def test_get_schema_url_for_signal_types_multiple_both_stable(self): + # DATABASE has higher version (1.25.0) than HTTP (1.21.0) + url = _get_schema_url_for_signal_types( + [ + _OpenTelemetryStabilitySignalType.HTTP, + _OpenTelemetryStabilitySignalType.DATABASE, + ] + ) + self.assertEqual(url, "https://opentelemetry.io/schemas/1.25.0") + + @stability_mode("http") + def test_get_schema_url_for_signal_types_mixed_modes(self): + # HTTP is stable (1.21.0), DATABASE is default (1.11.0) + # Should return HTTP version as it's higher + url = _get_schema_url_for_signal_types( + [ + _OpenTelemetryStabilitySignalType.HTTP, + _OpenTelemetryStabilitySignalType.DATABASE, + ] + ) + self.assertEqual(url, "https://opentelemetry.io/schemas/1.21.0") + + @stability_mode("database") + def test_get_schema_url_for_signal_types_database_only_stable(self): + # DATABASE is stable (1.25.0), HTTP is default (1.11.0) + # Should return DATABASE version as it's highest + url = _get_schema_url_for_signal_types( + [ + _OpenTelemetryStabilitySignalType.HTTP, + _OpenTelemetryStabilitySignalType.DATABASE, + ] + ) + self.assertEqual(url, "https://opentelemetry.io/schemas/1.25.0") + + @stability_mode("") + def test_get_schema_url_for_signal_types_empty_list(self): + url = _get_schema_url_for_signal_types([]) + self.assertEqual( + url, f"https://opentelemetry.io/schemas/{_LEGACY_SCHEMA_VERSION}" + ) + + @stability_mode("http/dup,database/dup") + def test_get_schema_url_for_signal_types_dup_modes(self): + url = _get_schema_url_for_signal_types( + [ + _OpenTelemetryStabilitySignalType.HTTP, + _OpenTelemetryStabilitySignalType.DATABASE, + ] + ) + self.assertEqual(url, "https://opentelemetry.io/schemas/1.25.0") + + @stability_mode("http,database,gen_ai_latest_experimental") + def test_get_schema_url_for_signal_types_with_gen_ai(self): + # GEN_AI should be highest at 1.26.0 + url = _get_schema_url_for_signal_types( + [ + _OpenTelemetryStabilitySignalType.HTTP, + _OpenTelemetryStabilitySignalType.DATABASE, + _OpenTelemetryStabilitySignalType.GEN_AI, + ] + ) + self.assertEqual(url, "https://opentelemetry.io/schemas/1.26.0") + + class TestOpenTelemetrySemConvStabilityHTTP(TestCase): def test_set_status_for_non_http_code_with_recording_span(self): span = Mock() @@ -443,3 +577,45 @@ def test_db_user_none_value(self): result = {} _set_db_user(result, None, sem_conv_opt_in_mode=_StabilityMode.DEFAULT) self.assertNotIn(DB_USER, result) + + def test_db_operation_default(self): + result = {} + _set_db_operation( + result, + "SELECT", + sem_conv_opt_in_mode=_StabilityMode.DEFAULT, + ) + self.assertIn(DB_OPERATION, result) + self.assertEqual(result[DB_OPERATION], "SELECT") + self.assertNotIn(DB_OPERATION_NAME, result) + + def test_db_operation_database_stable(self): + result = {} + _set_db_operation( + result, + "SELECT", + sem_conv_opt_in_mode=_StabilityMode.DATABASE, + ) + self.assertNotIn(DB_OPERATION, result) + self.assertIn(DB_OPERATION_NAME, result) + self.assertEqual(result[DB_OPERATION_NAME], "SELECT") + + def test_db_operation_database_dup(self): + result = {} + _set_db_operation( + result, + "SELECT", + sem_conv_opt_in_mode=_StabilityMode.DATABASE_DUP, + ) + self.assertIn(DB_OPERATION, result) + self.assertEqual(result[DB_OPERATION], "SELECT") + self.assertIn(DB_OPERATION_NAME, result) + self.assertEqual(result[DB_OPERATION_NAME], "SELECT") + + def test_db_operation_none_value(self): + result = {} + _set_db_operation( + result, None, sem_conv_opt_in_mode=_StabilityMode.DEFAULT + ) + self.assertNotIn(DB_OPERATION, result) + self.assertNotIn(DB_OPERATION_NAME, result) From 048b4add13a7dd93ba9359b25bead42a11332256 Mon Sep 17 00:00:00 2001 From: DylanRussell Date: Thu, 2 Apr 2026 16:14:19 -0400 Subject: [PATCH 45/78] Try to open file in `UploadCompletionHook` initializer with given path to ensure file upload works (#4390) * Add check for if file exists to completion hook * Add tests * Add CHANGELOG entry * Try to delete file * Fix linter * Fix test * Ignore unknown function.. --- util/opentelemetry-util-genai/CHANGELOG.md | 2 ++ .../util/genai/_upload/completion_hook.py | 32 +++++++++++++++---- .../tests/test_upload.py | 14 ++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index 1a93525f691..40b05bb3594 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4320](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4320)) - Add workflow invocation type to genAI utils ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4310](#4310)) +- Check if upload works at startup in initializer of the `UploadCompletionHook`, instead +of repeatedly failing on every upload ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4390](#4390)). ## Version 0.3b0 (2026-02-20) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py index 4f22861396a..79ebd3a1708 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py @@ -156,6 +156,30 @@ def __init__( f"Invalid {upload_format=}. Must be one of {_FORMATS}" ) self._format = upload_format + self._content_type = ( + "application/json" + if self._format == "json" + else "application/jsonl" + ) + test_path = posixpath.join( + self._base_path, + f".one_off_test_to_see_if_upload_works.{self._format}", + ) + try: + with self._fs.open( + test_path, "w", content_type=self._content_type + ) as file: + file.write("\n") + except Exception as exception: # pylint: disable=broad-exception-caught + raise ValueError( + f"Failed to write file to the following path, upload is not working: {test_path}.\n Got error: {exception}" + ) + # Try to delete the file.. But we don't explicitly ask people to grant the GCS delete IAM permission in our + # docs, so if delete fails just leave the file.. + try: + self._fs.rm_file(test_path) # pyright: ignore[reportUnknownMemberType] + except Exception: # pylint: disable=broad-exception-caught + pass # Use a ThreadPoolExecutor for its queueing and thread management. The semaphore # limits the number of queued tasks. If the queue is full, data will be dropped. @@ -271,13 +295,7 @@ def _do_upload( for message_idx, line in enumerate(message_lines): line[_MESSAGE_INDEX_KEY] = message_idx - content_type = ( - "application/json" - if self._format == "json" - else "application/jsonl" - ) - - with self._fs.open(path, "w", content_type=content_type) as file: + with self._fs.open(path, "w", content_type=self._content_type) as file: for message in message_lines: gen_ai_json_dump(message, file) file.write("\n") diff --git a/util/opentelemetry-util-genai/tests/test_upload.py b/util/opentelemetry-util-genai/tests/test_upload.py index aa5fcb5b4a1..c9611abf197 100644 --- a/util/opentelemetry-util-genai/tests/test_upload.py +++ b/util/opentelemetry-util-genai/tests/test_upload.py @@ -102,6 +102,8 @@ def setUp(self): self.hook = UploadCompletionHook( base_path=BASE_PATH, max_queue_size=MAXSIZE, lru_cache_max_size=5 ) + # 1 upload is done when creating the UploadHook to ensure upload works. Reset mock. + self.mock_fs.reset_mock() def tearDown(self) -> None: self.hook.shutdown() @@ -145,6 +147,18 @@ def test_upload_then_shutdown(self): "should have uploaded 4 files", ) + def test_failed_upload_causes_initializer_to_throw(self): + self.mock_fs.open.side_effect = ValueError("Failed for some reason!") + with self.assertRaisesRegex( + ValueError, + "Failed to write file to the following path, upload is not working:", + ): + UploadCompletionHook( + base_path=BASE_PATH, + max_queue_size=MAXSIZE, + lru_cache_max_size=5, + ) + def test_lru_cache_works(self): record = LogRecord() self.hook.on_completion( From 58b554ed8c3bb863cf9c4f9c1e71584e2a7c621e Mon Sep 17 00:00:00 2001 From: Dor Liberman <90474428+dorlib@users.noreply.github.com> Date: Fri, 3 Apr 2026 11:26:53 +0300 Subject: [PATCH 46/78] Fix/aiokafka 0.13 compatibility (#4379) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * tests(aiokafka): bump aiokafka 0.13 * tests(aiokafka): remove removed api_version argument from AIOKafkaProducer * fix(aiokafka): call serializers directly instead of _serialize * chore: add CHANGELOG entry for aiokafka 0.13 compatibility fix * tests(aiokafka): align tests to support python 3.9 * Apply suggestion from @xrmx --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 4 ++++ .../instrumentation/aiokafka/utils.py | 14 +++++++++++--- .../test-requirements.txt | 3 ++- .../tests/test_instrumentation.py | 9 +++++++-- .../tests/test_utils.py | 3 ++- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 257510fec09..a96dc5ef7da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4302](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4302)) - `opentelemetry-instrumentation-grpc`: Fix bidirectional streaming RPCs raising `AttributeError: 'generator' object has no attribute 'add_done_callback'` ([#4259](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4259)) +- `opentelemetry-instrumentation-aiokafka`: Fix compatibility with aiokafka 0.13 by calling + `_key_serializer`/`_value_serializer` directly instead of the internal `_serialize` method + whose signature changed in 0.13 from `(topic, key, value)` to `(key, value, headers)` + ([#4379](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4379)) ### Breaking changes diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py index 36bfb29efa4..8533a988589 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py @@ -162,9 +162,17 @@ async def _extract_send_partition( key = _extract_send_key(args, kwargs) value = _extract_send_value(args, kwargs) partition = _extract_argument("partition", 3, None, args, kwargs) - key_bytes, value_bytes = cast( - "tuple[bytes | None, bytes | None]", - instance._serialize(topic, key, value), # type: ignore[reportUnknownMemberType] + key_bytes = cast( + "bytes | None", + instance._key_serializer(key) # type: ignore[reportUnknownMemberType] + if instance._key_serializer # type: ignore[reportUnknownMemberType] + else key, + ) + value_bytes = cast( + "bytes | None", + instance._value_serializer(value) # type: ignore[reportUnknownMemberType] + if instance._value_serializer # type: ignore[reportUnknownMemberType] + else value, ) valid_types = (bytes, bytearray, memoryview, type(None)) if ( diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt b/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt index 460e58e0911..c29f54a732c 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/test-requirements.txt @@ -1,4 +1,5 @@ -aiokafka==0.11.0 +aiokafka==0.13.0; python_version >= "3.10" +aiokafka==0.12.0; python_version < "3.10" pytest==7.4.4 -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-aiokafka diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py index 8905c2a68ed..10f63d62196 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py @@ -14,9 +14,10 @@ from __future__ import annotations +import sys import uuid from typing import Any, Sequence, cast -from unittest import IsolatedAsyncioTestCase, TestCase, mock +from unittest import IsolatedAsyncioTestCase, TestCase, mock, skipIf import aiokafka from aiokafka import ( @@ -63,6 +64,10 @@ def test_instrument_api(self) -> None: ) +@skipIf( + sys.version_info < (3, 10), + "aiokafka >= 0.13 requires Python 3.10+", +) class TestAIOKafkaInstrumentation(TestBase, IsolatedAsyncioTestCase): @staticmethod def consumer_record_factory( @@ -126,7 +131,7 @@ async def consumer_factory(**consumer_kwargs: Any) -> AIOKafkaConsumer: @staticmethod async def producer_factory() -> AIOKafkaProducer: - producer = AIOKafkaProducer(api_version="1.0") + producer = AIOKafkaProducer() producer.client._wait_on_metadata = mock.AsyncMock() producer.client.bootstrap = mock.AsyncMock() diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py index a7dcbe6dcfa..5c3532692bb 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py @@ -370,7 +370,8 @@ async def test_create_consumer_span( async def test_kafka_properties_extractor(self): aiokafka_instance_mock = mock.Mock() - aiokafka_instance_mock._serialize.return_value = None, None + aiokafka_instance_mock._key_serializer = None + aiokafka_instance_mock._value_serializer = None aiokafka_instance_mock._partition.return_value = "partition" aiokafka_instance_mock.client._wait_on_metadata = mock.AsyncMock() assert ( From 4d266a06fa26246821a8927cec068fda523343e6 Mon Sep 17 00:00:00 2001 From: Dor Liberman <90474428+dorlib@users.noreply.github.com> Date: Fri, 3 Apr 2026 11:32:56 +0300 Subject: [PATCH 47/78] Fix/aiokafka tests fixes (#4384) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(aiokafka): close AIOKafkaProducer * fix(aiokafka): use AsyncMock to fix unawaited coroutine warning * docs(aiokafka): add CHANGELOG entry for test warning fixes * fix formatting * Apply suggestion from @xrmx --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 + .../tests/test_instrumentation.py | 68 ++++++++++--------- .../tests/test_utils.py | 3 +- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a96dc5ef7da..419a8a7c63d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4302](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4302)) - `opentelemetry-instrumentation-grpc`: Fix bidirectional streaming RPCs raising `AttributeError: 'generator' object has no attribute 'add_done_callback'` ([#4259](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4259)) +- `opentelemetry-instrumentation-aiokafka`: fix `Unclosed AIOKafkaProducer` warning and `RuntimeWarning: coroutine was never awaited` in tests + ([#4384](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4384)) - `opentelemetry-instrumentation-aiokafka`: Fix compatibility with aiokafka 0.13 by calling `_key_serializer`/`_value_serializer` directly instead of the internal `_serialize` method whose signature changed in 0.13 from `(topic, key, value)` to `(key, value, headers)` diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py index 10f63d62196..646232da356 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py @@ -503,37 +503,43 @@ async def test_send_and_wait(self) -> None: AIOKafkaInstrumentor().instrument(tracer_provider=self.tracer_provider) producer = await self.producer_factory() - add_message_mock: mock.AsyncMock = ( - producer._message_accumulator.add_message - ) - add_message_mock.side_effect = [mock.AsyncMock()(), mock.AsyncMock()()] - - tracer = self.tracer_provider.get_tracer(__name__) - with tracer.start_as_current_span("test_span") as span: - await producer.send_and_wait("topic_1", b"value_1") + try: + add_message_mock: mock.AsyncMock = ( + producer._message_accumulator.add_message + ) + add_message_mock.side_effect = [ + mock.AsyncMock()(), + mock.AsyncMock()(), + ] - add_message_mock.assert_awaited_with( - TopicPartition(topic="topic_1", partition=1), - None, - b"value_1", - 40.0, - timestamp_ms=None, - headers=[("traceparent", mock.ANY)], - ) - assert ( - add_message_mock.call_args_list[0] - .kwargs["headers"][0][1] - .startswith( - f"00-{format_trace_id(span.get_span_context().trace_id)}-".encode() + tracer = self.tracer_provider.get_tracer(__name__) + with tracer.start_as_current_span("test_span") as span: + await producer.send_and_wait("topic_1", b"value_1") + + add_message_mock.assert_awaited_with( + TopicPartition(topic="topic_1", partition=1), + None, + b"value_1", + 40.0, + timestamp_ms=None, + headers=[("traceparent", mock.ANY)], + ) + assert ( + add_message_mock.call_args_list[0] + .kwargs["headers"][0][1] + .startswith( + f"00-{format_trace_id(span.get_span_context().trace_id)}-".encode() + ) ) - ) - await producer.send_and_wait("topic_2", b"value_2") - add_message_mock.assert_awaited_with( - TopicPartition(topic="topic_2", partition=1), - None, - b"value_2", - 40.0, - timestamp_ms=None, - headers=[("traceparent", mock.ANY)], - ) + await producer.send_and_wait("topic_2", b"value_2") + add_message_mock.assert_awaited_with( + TopicPartition(topic="topic_2", partition=1), + None, + b"value_2", + 40.0, + timestamp_ms=None, + headers=[("traceparent", mock.ANY)], + ) + finally: + await producer.stop() diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py index 5c3532692bb..14e6d36178a 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_utils.py @@ -256,7 +256,7 @@ async def test_wrap_getmany( extract_bootstrap_servers: mock.MagicMock, _enrich_getmany_poll_span: mock.MagicMock, _enrich_getmany_topic_span: mock.MagicMock, - _create_consumer_span: mock.MagicMock, + _create_consumer_span: mock.AsyncMock, extract: mock.MagicMock, ) -> None: tracer = mock.MagicMock() @@ -270,6 +270,7 @@ async def test_wrap_getmany( } ) kafka_consumer = mock.MagicMock() + _create_consumer_span.return_value = mock.MagicMock() wrapped_getmany = _wrap_getmany(tracer, consume_hook) records = await wrapped_getmany( From 5430c75263286de074ae897201ee574706a59ad1 Mon Sep 17 00:00:00 2001 From: Steve Liu Date: Fri, 3 Apr 2026 02:01:46 -0700 Subject: [PATCH 48/78] feat(asgi): respect suppress_http_instrumentation in ASGI middleware (#4375) Add is_http_instrumentation_enabled() check in OpenTelemetryMiddleware.__call__ so ASGI server spans are skipped when HTTP instrumentation is suppressed. Every other HTTP instrumentor (client and server) already honors this flag. ASGI was the only one that did not. Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 2 ++ .../opentelemetry/instrumentation/asgi/__init__.py | 10 ++++++++-- .../tests/test_asgi_middleware.py | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 419a8a7c63d..d9e48cd6df8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation-asgi`: Respect `suppress_http_instrumentation` context in ASGI middleware to skip server span creation when HTTP instrumentation is suppressed + ([#4375](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4375)) - `opentelemetry-instrumentation-confluent-kafka`: Loosen confluent-kafka upper bound to <3.0.0 ([#4289](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4289)) - `opentelemetry-instrumentation`: Add support for wrapt 2.x diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 59c5083ada8..e28315f502e 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -255,7 +255,10 @@ def client_response_hook(span: Span, scope: Scope, message: dict[str, Any]): from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, ) -from opentelemetry.instrumentation.utils import _start_internal_or_server_span +from opentelemetry.instrumentation.utils import ( + _start_internal_or_server_span, + is_http_instrumentation_enabled, +) from opentelemetry.metrics import get_meter from opentelemetry.propagators.textmap import Getter, Setter from opentelemetry.semconv._incubating.attributes.http_attributes import ( @@ -745,7 +748,10 @@ async def __call__( send: An awaitable callable taking a single dictionary as argument. """ start = default_timer() - if scope["type"] not in ("http", "websocket"): + if not is_http_instrumentation_enabled() or scope["type"] not in ( + "http", + "websocket", + ): return await self.app(scope, receive, send) _, _, url = get_host_port_url_tuple(scope) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index f716c9f2f1e..b14f207d8a5 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -37,6 +37,7 @@ get_global_response_propagator, set_global_response_propagator, ) +from opentelemetry.instrumentation.utils import suppress_http_instrumentation from opentelemetry.sdk import resources from opentelemetry.sdk.metrics.export import ( HistogramDataPoint, @@ -1880,6 +1881,19 @@ async def test_no_excluded_urls(self): spans = self.get_finished_spans() self.assertGreater(len(spans), 0) + async def test_suppress_http_instrumentation(self): + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + + async def suppression_wrapper(scope, receive, send): + with suppress_http_instrumentation(): + await app(scope, receive, send) + + self.seed_app(suppression_wrapper) + await self.send_default_request() + await self.get_all_output() + spans = self.get_finished_spans() + self.assertEqual(len(spans), 0) + class TestAsgiAttributes(unittest.TestCase): def setUp(self): From f83b34c2e18aa631be6030c934b9601711abe201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Fri, 3 Apr 2026 13:59:31 -0300 Subject: [PATCH 49/78] introduce alls-green action for required checks (#4388) * port alls-green to -contrib Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix typo Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .github/workflows/ci.yml | 38 + ...ntrib_test_0.yml => core_contrib_test.yml} | 2 +- .github/workflows/generate_workflows.py | 2 + .../src/generate_workflows_lib/__init__.py | 41 +- .../src/generate_workflows_lib/ci.yml.j2 | 38 + .../src/generate_workflows_lib/lint.yml.j2 | 11 +- .../src/generate_workflows_lib/misc.yml.j2 | 11 +- .../src/generate_workflows_lib/test.yml.j2 | 11 +- .github/workflows/{lint_0.yml => lint.yml} | 11 +- .github/workflows/{misc_0.yml => misc.yml} | 11 +- .github/workflows/test.yml | 14826 ++++++++++++++++ .github/workflows/test_0.yml | 4782 ----- .github/workflows/test_1.yml | 4782 ----- .github/workflows/test_2.yml | 4782 ----- .github/workflows/test_3.yml | 583 - README.md | 7 +- 16 files changed, 14940 insertions(+), 14998 deletions(-) create mode 100644 .github/workflows/ci.yml rename .github/workflows/{core_contrib_test_0.yml => core_contrib_test.yml} (99%) create mode 100644 .github/workflows/generate_workflows_lib/src/generate_workflows_lib/ci.yml.j2 rename .github/workflows/{lint_0.yml => lint.yml} (99%) rename .github/workflows/{misc_0.yml => misc.yml} (96%) create mode 100644 .github/workflows/test.yml delete mode 100644 .github/workflows/test_0.yml delete mode 100644 .github/workflows/test_1.yml delete mode 100644 .github/workflows/test_2.yml delete mode 100644 .github/workflows/test_3.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000000..a1963283de4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: CI + +on: + push: + branches: + - 'main' + pull_request: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + misc: + uses: ./.github/workflows/misc.yml + lint: + uses: ./.github/workflows/lint.yml + tests: + uses: ./.github/workflows/test.yml + + check: + if: always() + needs: + - misc + - lint + - tests + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/core_contrib_test_0.yml b/.github/workflows/core_contrib_test.yml similarity index 99% rename from .github/workflows/core_contrib_test_0.yml rename to .github/workflows/core_contrib_test.yml index 3f312768732..4653f3d360f 100644 --- a/.github/workflows/core_contrib_test_0.yml +++ b/.github/workflows/core_contrib_test.yml @@ -1,7 +1,7 @@ # Do not edit this file. # This file is generated automatically by executing tox -e generate-workflows -name: Core Contrib Test 0 +name: Core Contrib Test on: workflow_call: diff --git a/.github/workflows/generate_workflows.py b/.github/workflows/generate_workflows.py index 09391a240cc..7aacf708f0d 100644 --- a/.github/workflows/generate_workflows.py +++ b/.github/workflows/generate_workflows.py @@ -1,6 +1,7 @@ from pathlib import Path from generate_workflows_lib import ( + generate_ci_workflow, generate_contrib_workflow, generate_lint_workflow, generate_misc_workflow, @@ -14,3 +15,4 @@ generate_lint_workflow(tox_ini_path, workflows_directory_path) generate_misc_workflow(tox_ini_path, workflows_directory_path) generate_contrib_workflow(workflows_directory_path) +generate_ci_workflow(workflows_directory_path) diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py index 30f306ea5c0..a2e628a09ec 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -172,25 +172,18 @@ def get_misc_job_datas(tox_envs: list) -> list: def _generate_workflow( - job_datas: list, name: str, workflow_directory_path: Path, max_jobs=250 -): - # Github seems to limit the amount of jobs in a workflow file, that is why - # they are split in groups of 250 per workflow file. - for file_number, job_datas in enumerate( - [ - job_datas[index : index + max_jobs] - for index in range(0, len(job_datas), max_jobs) - ] - ): - with open( - workflow_directory_path.joinpath(f"{name}_{file_number}.yml"), "w" - ) as test_yml_file: - test_yml_file.write( - Environment(loader=FileSystemLoader(Path(__file__).parent)) - .get_template(f"{name}.yml.j2") - .render(job_datas=job_datas, file_number=file_number) + job_datas: list, name: str, workflow_directory_path: Path +) -> None: + env = Environment(loader=FileSystemLoader(Path(__file__).parent)) + with open( + workflow_directory_path.joinpath(f"{name}.yml"), "w" + ) as yml_file: + yml_file.write( + env.get_template(f"{name}.yml.j2").render( + job_datas=job_datas, ) - test_yml_file.write("\n") + ) + yml_file.write("\n") def generate_test_workflow( @@ -235,3 +228,15 @@ def generate_misc_workflow( "misc", workflow_directory_path, ) + + +def generate_ci_workflow( + workflow_directory_path: Path, +) -> None: + with open(workflow_directory_path.joinpath("ci.yml"), "w") as ci_yml_file: + ci_yml_file.write( + Environment(loader=FileSystemLoader(Path(__file__).parent)) + .get_template("ci.yml.j2") + .render() + ) + ci_yml_file.write("\n") diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/ci.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/ci.yml.j2 new file mode 100644 index 00000000000..746adf13b65 --- /dev/null +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/ci.yml.j2 @@ -0,0 +1,38 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: CI + +on: + push: + branches: + - 'main' + pull_request: + +permissions: + contents: read + +concurrency: + group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %} + cancel-in-progress: true + +jobs: + misc: + uses: ./.github/workflows/misc.yml + lint: + uses: ./.github/workflows/lint.yml + tests: + uses: ./.github/workflows/test.yml + + check: + if: always() + needs: + - misc + - lint + - tests + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${% raw %}{{ toJSON(needs) }}{% endraw %} diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 index ef5e417d423..db05da7a6b0 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2 @@ -1,21 +1,14 @@ # Do not edit this file. # This file is generated automatically by executing tox -e generate-workflows -name: Lint {{ file_number }} +name: Lint on: - push: - branches: - - 'main' - pull_request: + workflow_call: permissions: contents: read -concurrency: - group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %} - cancel-in-progress: true - env: # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' # For PRs you can change the inner fallback ('main') diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 index 20ad381d4a0..c356b8396d8 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2 @@ -1,21 +1,14 @@ # Do not edit this file. # This file is generated automatically by executing tox -e generate-workflows -name: Misc {{ file_number }} +name: Misc on: - push: - branches: - - 'main' - pull_request: + workflow_call: permissions: contents: read -concurrency: - group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %} - cancel-in-progress: true - env: # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' # For PRs you can change the inner fallback ('main') diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 index a0041c8b630..5002f85f4dc 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/test.yml.j2 @@ -1,21 +1,14 @@ # Do not edit this file. # This file is generated automatically by executing tox -e generate-workflows -name: Test {{ file_number }} +name: Test on: - push: - branches: - - 'main' - pull_request: + workflow_call: permissions: contents: read -concurrency: - group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %} - cancel-in-progress: true - env: # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' # For PRs you can change the inner fallback ('main') diff --git a/.github/workflows/lint_0.yml b/.github/workflows/lint.yml similarity index 99% rename from .github/workflows/lint_0.yml rename to .github/workflows/lint.yml index fdd1a954a5a..6bf3c631cd8 100644 --- a/.github/workflows/lint_0.yml +++ b/.github/workflows/lint.yml @@ -1,21 +1,14 @@ # Do not edit this file. # This file is generated automatically by executing tox -e generate-workflows -name: Lint 0 +name: Lint on: - push: - branches: - - 'main' - pull_request: + workflow_call: permissions: contents: read -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - env: # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' # For PRs you can change the inner fallback ('main') diff --git a/.github/workflows/misc_0.yml b/.github/workflows/misc.yml similarity index 96% rename from .github/workflows/misc_0.yml rename to .github/workflows/misc.yml index bf8b902de14..652d90942ae 100644 --- a/.github/workflows/misc_0.yml +++ b/.github/workflows/misc.yml @@ -1,21 +1,14 @@ # Do not edit this file. # This file is generated automatically by executing tox -e generate-workflows -name: Misc 0 +name: Misc on: - push: - branches: - - 'main' - pull_request: + workflow_call: permissions: contents: read -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - env: # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' # For PRs you can change the inner fallback ('main') diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000000..171d36f716b --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,14826 @@ +# Do not edit this file. +# This file is generated automatically by executing tox -e generate-workflows + +name: Test + +on: + workflow_call: + +permissions: + contents: read + +env: + # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' + # For PRs you can change the inner fallback ('main') + # For pushes you change the outer fallback ('main') + # The logic below is used during releases and depends on having an equivalent branch name in the core repo. + CORE_REPO_SHA: ${{ github.event_name == 'pull_request' && ( + contains(github.event.pull_request.labels.*.name, 'prepare-release') && github.event.pull_request.head.ref || + contains(github.event.pull_request.labels.*.name, 'backport') && github.event.pull_request.base.ref || + 'main' + ) || 'main' }} + CONTRIB_REPO_SHA: main + PIP_EXISTS_ACTION: w + +jobs: + + py39-test-instrumentation-openai-v2-oldest_ubuntu-latest: + name: instrumentation-openai-v2-oldest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-openai-v2-oldest -- -ra + + py39-test-instrumentation-openai-v2-latest_ubuntu-latest: + name: instrumentation-openai-v2-latest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-openai-v2-latest -- -ra + + py310-test-instrumentation-openai-v2-oldest_ubuntu-latest: + name: instrumentation-openai-v2-oldest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-openai-v2-oldest -- -ra + + py310-test-instrumentation-openai-v2-latest_ubuntu-latest: + name: instrumentation-openai-v2-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-openai-v2-latest -- -ra + + py311-test-instrumentation-openai-v2-oldest_ubuntu-latest: + name: instrumentation-openai-v2-oldest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-openai-v2-oldest -- -ra + + py311-test-instrumentation-openai-v2-latest_ubuntu-latest: + name: instrumentation-openai-v2-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-openai-v2-latest -- -ra + + py312-test-instrumentation-openai-v2-oldest_ubuntu-latest: + name: instrumentation-openai-v2-oldest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-openai-v2-oldest -- -ra + + py312-test-instrumentation-openai-v2-latest_ubuntu-latest: + name: instrumentation-openai-v2-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-openai-v2-latest -- -ra + + py313-test-instrumentation-openai-v2-oldest_ubuntu-latest: + name: instrumentation-openai-v2-oldest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-openai-v2-oldest -- -ra + + py313-test-instrumentation-openai-v2-latest_ubuntu-latest: + name: instrumentation-openai-v2-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-openai-v2-latest -- -ra + + py314-test-instrumentation-openai-v2-oldest_ubuntu-latest: + name: instrumentation-openai-v2-oldest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-openai-v2-oldest -- -ra + + py314-test-instrumentation-openai-v2-latest_ubuntu-latest: + name: instrumentation-openai-v2-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-openai-v2-latest -- -ra + + pypy3-test-instrumentation-openai-v2-oldest_ubuntu-latest: + name: instrumentation-openai-v2-oldest pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-openai-v2-oldest -- -ra + + pypy3-test-instrumentation-openai-v2-latest_ubuntu-latest: + name: instrumentation-openai-v2-latest pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-openai-v2-latest -- -ra + + py310-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: + name: instrumentation-openai_agents-v2-oldest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-openai_agents-v2-oldest -- -ra + + py310-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: + name: instrumentation-openai_agents-v2-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-openai_agents-v2-latest -- -ra + + py311-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: + name: instrumentation-openai_agents-v2-oldest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-openai_agents-v2-oldest -- -ra + + py311-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: + name: instrumentation-openai_agents-v2-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-openai_agents-v2-latest -- -ra + + py312-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: + name: instrumentation-openai_agents-v2-oldest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-openai_agents-v2-oldest -- -ra + + py312-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: + name: instrumentation-openai_agents-v2-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-openai_agents-v2-latest -- -ra + + py313-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: + name: instrumentation-openai_agents-v2-oldest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-openai_agents-v2-oldest -- -ra + + py313-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: + name: instrumentation-openai_agents-v2-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-openai_agents-v2-latest -- -ra + + py314-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: + name: instrumentation-openai_agents-v2-oldest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-openai_agents-v2-oldest -- -ra + + py314-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: + name: instrumentation-openai_agents-v2-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-openai_agents-v2-latest -- -ra + + py39-test-instrumentation-vertexai-oldest_ubuntu-latest: + name: instrumentation-vertexai-oldest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-vertexai-oldest -- -ra + + py39-test-instrumentation-vertexai-latest_ubuntu-latest: + name: instrumentation-vertexai-latest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-vertexai-latest -- -ra + + py310-test-instrumentation-vertexai-oldest_ubuntu-latest: + name: instrumentation-vertexai-oldest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-vertexai-oldest -- -ra + + py310-test-instrumentation-vertexai-latest_ubuntu-latest: + name: instrumentation-vertexai-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-vertexai-latest -- -ra + + py311-test-instrumentation-vertexai-oldest_ubuntu-latest: + name: instrumentation-vertexai-oldest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-vertexai-oldest -- -ra + + py311-test-instrumentation-vertexai-latest_ubuntu-latest: + name: instrumentation-vertexai-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-vertexai-latest -- -ra + + py312-test-instrumentation-vertexai-oldest_ubuntu-latest: + name: instrumentation-vertexai-oldest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-vertexai-oldest -- -ra + + py312-test-instrumentation-vertexai-latest_ubuntu-latest: + name: instrumentation-vertexai-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-vertexai-latest -- -ra + + py313-test-instrumentation-vertexai-oldest_ubuntu-latest: + name: instrumentation-vertexai-oldest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-vertexai-oldest -- -ra + + py313-test-instrumentation-vertexai-latest_ubuntu-latest: + name: instrumentation-vertexai-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-vertexai-latest -- -ra + + py314-test-instrumentation-vertexai-oldest_ubuntu-latest: + name: instrumentation-vertexai-oldest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-vertexai-oldest -- -ra + + py314-test-instrumentation-vertexai-latest_ubuntu-latest: + name: instrumentation-vertexai-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-vertexai-latest -- -ra + + py39-test-instrumentation-google-genai-oldest_ubuntu-latest: + name: instrumentation-google-genai-oldest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-google-genai-oldest -- -ra + + py39-test-instrumentation-google-genai-latest_ubuntu-latest: + name: instrumentation-google-genai-latest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-google-genai-latest -- -ra + + py310-test-instrumentation-google-genai-oldest_ubuntu-latest: + name: instrumentation-google-genai-oldest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-google-genai-oldest -- -ra + + py310-test-instrumentation-google-genai-latest_ubuntu-latest: + name: instrumentation-google-genai-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-google-genai-latest -- -ra + + py311-test-instrumentation-google-genai-oldest_ubuntu-latest: + name: instrumentation-google-genai-oldest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-google-genai-oldest -- -ra + + py311-test-instrumentation-google-genai-latest_ubuntu-latest: + name: instrumentation-google-genai-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-google-genai-latest -- -ra + + py312-test-instrumentation-google-genai-oldest_ubuntu-latest: + name: instrumentation-google-genai-oldest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-google-genai-oldest -- -ra + + py312-test-instrumentation-google-genai-latest_ubuntu-latest: + name: instrumentation-google-genai-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-google-genai-latest -- -ra + + py313-test-instrumentation-google-genai-oldest_ubuntu-latest: + name: instrumentation-google-genai-oldest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-google-genai-oldest -- -ra + + py313-test-instrumentation-google-genai-latest_ubuntu-latest: + name: instrumentation-google-genai-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-google-genai-latest -- -ra + + py314-test-instrumentation-google-genai-oldest_ubuntu-latest: + name: instrumentation-google-genai-oldest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-google-genai-oldest -- -ra + + py314-test-instrumentation-google-genai-latest_ubuntu-latest: + name: instrumentation-google-genai-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-google-genai-latest -- -ra + + py39-test-instrumentation-anthropic-oldest_ubuntu-latest: + name: instrumentation-anthropic-oldest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-anthropic-oldest -- -ra + + py39-test-instrumentation-anthropic-latest_ubuntu-latest: + name: instrumentation-anthropic-latest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-anthropic-latest -- -ra + + py310-test-instrumentation-anthropic-oldest_ubuntu-latest: + name: instrumentation-anthropic-oldest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-anthropic-oldest -- -ra + + py310-test-instrumentation-anthropic-latest_ubuntu-latest: + name: instrumentation-anthropic-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-anthropic-latest -- -ra + + py311-test-instrumentation-anthropic-oldest_ubuntu-latest: + name: instrumentation-anthropic-oldest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-anthropic-oldest -- -ra + + py311-test-instrumentation-anthropic-latest_ubuntu-latest: + name: instrumentation-anthropic-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-anthropic-latest -- -ra + + py312-test-instrumentation-anthropic-oldest_ubuntu-latest: + name: instrumentation-anthropic-oldest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-anthropic-oldest -- -ra + + py312-test-instrumentation-anthropic-latest_ubuntu-latest: + name: instrumentation-anthropic-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-anthropic-latest -- -ra + + py313-test-instrumentation-anthropic-oldest_ubuntu-latest: + name: instrumentation-anthropic-oldest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-anthropic-oldest -- -ra + + py313-test-instrumentation-anthropic-latest_ubuntu-latest: + name: instrumentation-anthropic-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-anthropic-latest -- -ra + + py314-test-instrumentation-anthropic-oldest_ubuntu-latest: + name: instrumentation-anthropic-oldest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-anthropic-oldest -- -ra + + py314-test-instrumentation-anthropic-latest_ubuntu-latest: + name: instrumentation-anthropic-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-anthropic-latest -- -ra + + py310-test-instrumentation-claude-agent-sdk-oldest_ubuntu-latest: + name: instrumentation-claude-agent-sdk-oldest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-claude-agent-sdk-oldest -- -ra + + py310-test-instrumentation-claude-agent-sdk-latest_ubuntu-latest: + name: instrumentation-claude-agent-sdk-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-claude-agent-sdk-latest -- -ra + + py311-test-instrumentation-claude-agent-sdk-oldest_ubuntu-latest: + name: instrumentation-claude-agent-sdk-oldest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-claude-agent-sdk-oldest -- -ra + + py311-test-instrumentation-claude-agent-sdk-latest_ubuntu-latest: + name: instrumentation-claude-agent-sdk-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-claude-agent-sdk-latest -- -ra + + py312-test-instrumentation-claude-agent-sdk-oldest_ubuntu-latest: + name: instrumentation-claude-agent-sdk-oldest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-claude-agent-sdk-oldest -- -ra + + py312-test-instrumentation-claude-agent-sdk-latest_ubuntu-latest: + name: instrumentation-claude-agent-sdk-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-claude-agent-sdk-latest -- -ra + + py313-test-instrumentation-claude-agent-sdk-oldest_ubuntu-latest: + name: instrumentation-claude-agent-sdk-oldest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-claude-agent-sdk-oldest -- -ra + + py313-test-instrumentation-claude-agent-sdk-latest_ubuntu-latest: + name: instrumentation-claude-agent-sdk-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-claude-agent-sdk-latest -- -ra + + py39-test-resource-detector-containerid_ubuntu-latest: + name: resource-detector-containerid 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-resource-detector-containerid -- -ra + + py310-test-resource-detector-containerid_ubuntu-latest: + name: resource-detector-containerid 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-resource-detector-containerid -- -ra + + py311-test-resource-detector-containerid_ubuntu-latest: + name: resource-detector-containerid 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-resource-detector-containerid -- -ra + + py312-test-resource-detector-containerid_ubuntu-latest: + name: resource-detector-containerid 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-resource-detector-containerid -- -ra + + py313-test-resource-detector-containerid_ubuntu-latest: + name: resource-detector-containerid 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-resource-detector-containerid -- -ra + + py314-test-resource-detector-containerid_ubuntu-latest: + name: resource-detector-containerid 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-resource-detector-containerid -- -ra + + pypy3-test-resource-detector-containerid_ubuntu-latest: + name: resource-detector-containerid pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-resource-detector-containerid -- -ra + + py39-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-resource-detector-azure-0 -- -ra + + py39-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-resource-detector-azure-1 -- -ra + + py310-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-resource-detector-azure-0 -- -ra + + py310-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-resource-detector-azure-1 -- -ra + + py311-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-resource-detector-azure-0 -- -ra + + py311-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-resource-detector-azure-1 -- -ra + + py312-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-resource-detector-azure-0 -- -ra + + py312-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-resource-detector-azure-1 -- -ra + + py313-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-resource-detector-azure-0 -- -ra + + py313-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-resource-detector-azure-1 -- -ra + + py314-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-resource-detector-azure-0 -- -ra + + py314-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-resource-detector-azure-1 -- -ra + + pypy3-test-resource-detector-azure-0_ubuntu-latest: + name: resource-detector-azure-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-resource-detector-azure-0 -- -ra + + pypy3-test-resource-detector-azure-1_ubuntu-latest: + name: resource-detector-azure-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-resource-detector-azure-1 -- -ra + + py39-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-sdk-extension-aws-0 -- -ra + + py39-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-sdk-extension-aws-1 -- -ra + + py310-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-sdk-extension-aws-0 -- -ra + + py310-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-sdk-extension-aws-1 -- -ra + + py311-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-sdk-extension-aws-0 -- -ra + + py311-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-sdk-extension-aws-1 -- -ra + + py312-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-sdk-extension-aws-0 -- -ra + + py312-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-sdk-extension-aws-1 -- -ra + + py313-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-sdk-extension-aws-0 -- -ra + + py313-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-sdk-extension-aws-1 -- -ra + + py314-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-sdk-extension-aws-0 -- -ra + + py314-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-sdk-extension-aws-1 -- -ra + + pypy3-test-sdk-extension-aws-0_ubuntu-latest: + name: sdk-extension-aws-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-sdk-extension-aws-0 -- -ra + + pypy3-test-sdk-extension-aws-1_ubuntu-latest: + name: sdk-extension-aws-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-sdk-extension-aws-1 -- -ra + + py39-test-distro_ubuntu-latest: + name: distro 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-distro -- -ra + + py310-test-distro_ubuntu-latest: + name: distro 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-distro -- -ra + + py311-test-distro_ubuntu-latest: + name: distro 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-distro -- -ra + + py312-test-distro_ubuntu-latest: + name: distro 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-distro -- -ra + + py313-test-distro_ubuntu-latest: + name: distro 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-distro -- -ra + + py314-test-distro_ubuntu-latest: + name: distro 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-distro -- -ra + + pypy3-test-distro_ubuntu-latest: + name: distro pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-distro -- -ra + + py39-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py39-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py310-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py310-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py311-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py311-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py312-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py312-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py313-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py313-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py314-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opentelemetry-instrumentation-wrapt1 -- -ra + + py314-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opentelemetry-instrumentation-wrapt2 -- -ra + + pypy3-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: + name: opentelemetry-instrumentation-wrapt2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-opentelemetry-instrumentation-wrapt2 -- -ra + + py39-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aiohttp-client -- -ra + + py310-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aiohttp-client -- -ra + + py311-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aiohttp-client -- -ra + + py312-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aiohttp-client -- -ra + + py313-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aiohttp-client -- -ra + + py314-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aiohttp-client -- -ra + + pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: + name: instrumentation-aiohttp-client pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aiohttp-client -- -ra + + py39-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aiohttp-server -- -ra + + py310-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aiohttp-server -- -ra + + py311-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aiohttp-server -- -ra + + py312-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aiohttp-server -- -ra + + py313-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aiohttp-server -- -ra + + py314-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aiohttp-server -- -ra + + pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: + name: instrumentation-aiohttp-server pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra + + py39-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aiopg-wrapt1 -- -ra + + py39-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aiopg-wrapt2 -- -ra + + py310-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aiopg-wrapt1 -- -ra + + py310-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aiopg-wrapt2 -- -ra + + py311-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aiopg-wrapt1 -- -ra + + py311-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aiopg-wrapt2 -- -ra + + py312-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aiopg-wrapt1 -- -ra + + py312-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aiopg-wrapt2 -- -ra + + py313-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aiopg-wrapt1 -- -ra + + py313-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aiopg-wrapt2 -- -ra + + py314-test-instrumentation-aiopg-wrapt1_ubuntu-latest: + name: instrumentation-aiopg-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aiopg-wrapt1 -- -ra + + py314-test-instrumentation-aiopg-wrapt2_ubuntu-latest: + name: instrumentation-aiopg-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aiopg-wrapt2 -- -ra + + py39-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aws-lambda -- -ra + + py310-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aws-lambda -- -ra + + py311-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aws-lambda -- -ra + + py312-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aws-lambda -- -ra + + py313-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aws-lambda -- -ra + + py314-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aws-lambda -- -ra + + pypy3-test-instrumentation-aws-lambda_ubuntu-latest: + name: instrumentation-aws-lambda pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra + + py39-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-0-wrapt1 -- -ra + + py39-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-0-wrapt2 -- -ra + + py39-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-1-wrapt1 -- -ra + + py39-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra + + py310-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-0-wrapt1 -- -ra + + py310-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-0-wrapt2 -- -ra + + py310-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-1-wrapt1 -- -ra + + py310-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-1-wrapt2 -- -ra + + py311-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-0-wrapt1 -- -ra + + py311-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-0-wrapt2 -- -ra + + py311-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-1-wrapt1 -- -ra + + py311-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-1-wrapt2 -- -ra + + py312-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-0-wrapt1 -- -ra + + py312-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-0-wrapt2 -- -ra + + py312-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-1-wrapt1 -- -ra + + py312-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-1-wrapt2 -- -ra + + py313-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-0-wrapt1 -- -ra + + py313-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-0-wrapt2 -- -ra + + py313-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-1-wrapt1 -- -ra + + py313-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-1-wrapt2 -- -ra + + py314-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: + name: instrumentation-botocore-0-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-botocore-0-wrapt1 -- -ra + + py314-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: + name: instrumentation-botocore-0-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-botocore-0-wrapt2 -- -ra + + py314-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: + name: instrumentation-botocore-1-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-botocore-1-wrapt1 -- -ra + + py314-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: + name: instrumentation-botocore-1-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-botocore-1-wrapt2 -- -ra + + py39-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-2 -- -ra + + py39-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-botocore-3 -- -ra + + py310-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-2 -- -ra + + py310-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-botocore-3 -- -ra + + py311-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-2 -- -ra + + py311-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-botocore-3 -- -ra + + py312-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-2 -- -ra + + py312-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-botocore-3 -- -ra + + py313-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-2 -- -ra + + py313-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-botocore-3 -- -ra + + py314-test-instrumentation-botocore-2_ubuntu-latest: + name: instrumentation-botocore-2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-botocore-2 -- -ra + + py314-test-instrumentation-botocore-3_ubuntu-latest: + name: instrumentation-botocore-3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-botocore-3 -- -ra + + py39-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-boto3sqs -- -ra + + py310-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-boto3sqs -- -ra + + py311-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-boto3sqs -- -ra + + py312-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-boto3sqs -- -ra + + py313-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-boto3sqs -- -ra + + py314-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-boto3sqs -- -ra + + pypy3-test-instrumentation-boto3sqs_ubuntu-latest: + name: instrumentation-boto3sqs pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra + + py39-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-django-0 -- -ra + + py39-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-django-1 -- -ra + + py39-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-django-2 -- -ra + + py310-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-django-1 -- -ra + + py310-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-django-3 -- -ra + + py311-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-django-1 -- -ra + + py311-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-django-3 -- -ra + + py312-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-django-1 -- -ra + + py312-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-django-3 -- -ra + + py313-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-django-3 -- -ra + + py314-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-django-3 -- -ra + + pypy3-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-django-0 -- -ra + + pypy3-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-django-1 -- -ra + + py39-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-dbapi-wrapt1 -- -ra + + py39-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra + + py310-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-dbapi-wrapt1 -- -ra + + py310-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-dbapi-wrapt2 -- -ra + + py311-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-dbapi-wrapt1 -- -ra + + py311-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-dbapi-wrapt2 -- -ra + + py312-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-dbapi-wrapt1 -- -ra + + py312-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-dbapi-wrapt2 -- -ra + + py313-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-dbapi-wrapt1 -- -ra + + py313-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-dbapi-wrapt2 -- -ra + + py314-test-instrumentation-dbapi-wrapt1_ubuntu-latest: + name: instrumentation-dbapi-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-dbapi-wrapt1 -- -ra + + py314-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-dbapi-wrapt2 -- -ra + + pypy3-test-instrumentation-dbapi-wrapt2_ubuntu-latest: + name: instrumentation-dbapi-wrapt2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-dbapi-wrapt2 -- -ra + + py39-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-asyncclick -- -ra + + py310-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-asyncclick -- -ra + + py311-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-asyncclick -- -ra + + py312-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-asyncclick -- -ra + + py313-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-asyncclick -- -ra + + py314-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-asyncclick -- -ra + + pypy3-test-instrumentation-asyncclick_ubuntu-latest: + name: instrumentation-asyncclick pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-asyncclick -- -ra + + py39-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-click -- -ra + + py310-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-click -- -ra + + py311-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-click -- -ra + + py312-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-click -- -ra + + py313-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-click -- -ra + + py314-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-click -- -ra + + pypy3-test-instrumentation-click_ubuntu-latest: + name: instrumentation-click pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-click -- -ra + + py39-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra + + py39-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra + + py39-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra + + py310-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra + + py310-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra + + py310-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra + + py311-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra + + py311-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra + + py311-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra + + py312-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra + + py312-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra + + py312-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra + + py313-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-0 -- -ra + + py313-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-1 -- -ra + + py313-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-elasticsearch-2 -- -ra + + py314-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-elasticsearch-0 -- -ra + + py314-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-elasticsearch-1 -- -ra + + py314-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-elasticsearch-2 -- -ra + + pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: + name: instrumentation-elasticsearch-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra + + pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: + name: instrumentation-elasticsearch-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra + + pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: + name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra + + py39-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-0 -- -ra + + py39-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-1 -- -ra + + py39-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-2 -- -ra + + py39-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-falcon-3 -- -ra + + py310-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-falcon-1 -- -ra + + py310-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-falcon-2 -- -ra + + py310-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-falcon-3 -- -ra + + py310-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-falcon-4 -- -ra + + py311-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-falcon-1 -- -ra + + py311-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-falcon-2 -- -ra + + py311-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-falcon-3 -- -ra + + py311-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-falcon-4 -- -ra + + py312-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-falcon-1 -- -ra + + py312-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-falcon-2 -- -ra + + py312-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-falcon-3 -- -ra + + py312-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-falcon-4 -- -ra + + py313-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-falcon-4 -- -ra + + py314-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-falcon-4 -- -ra + + pypy3-test-instrumentation-falcon-0_ubuntu-latest: + name: instrumentation-falcon-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra + + pypy3-test-instrumentation-falcon-1_ubuntu-latest: + name: instrumentation-falcon-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra + + pypy3-test-instrumentation-falcon-2_ubuntu-latest: + name: instrumentation-falcon-2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra + + pypy3-test-instrumentation-falcon-3_ubuntu-latest: + name: instrumentation-falcon-3 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-3 -- -ra + + pypy3-test-instrumentation-falcon-4_ubuntu-latest: + name: instrumentation-falcon-4 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-falcon-4 -- -ra + + py39-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-fastapi -- -ra + + py310-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-fastapi -- -ra + + py311-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-fastapi -- -ra + + py312-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-fastapi -- -ra + + py313-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-fastapi -- -ra + + py314-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-fastapi -- -ra + + pypy3-test-instrumentation-fastapi_ubuntu-latest: + name: instrumentation-fastapi pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-fastapi -- -ra + + py39-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-flask-0 -- -ra + + py39-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-flask-1 -- -ra + + py39-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-flask-2 -- -ra + + py39-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-flask-3 -- -ra + + py310-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-flask-0 -- -ra + + py310-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-flask-1 -- -ra + + py310-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-flask-2 -- -ra + + py310-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-flask-3 -- -ra + + py311-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-flask-0 -- -ra + + py311-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-flask-1 -- -ra + + py311-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-flask-2 -- -ra + + py311-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-flask-3 -- -ra + + py312-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-flask-0 -- -ra + + py312-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-flask-1 -- -ra + + py312-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-flask-2 -- -ra + + py312-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-flask-3 -- -ra + + py313-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-flask-0 -- -ra + + py313-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-flask-1 -- -ra + + py313-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-flask-2 -- -ra + + py313-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-flask-3 -- -ra + + py314-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-flask-0 -- -ra + + py314-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-flask-1 -- -ra + + py314-test-instrumentation-flask-2_ubuntu-latest: + name: instrumentation-flask-2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-flask-2 -- -ra + + py314-test-instrumentation-flask-3_ubuntu-latest: + name: instrumentation-flask-3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-flask-3 -- -ra + + pypy3-test-instrumentation-flask-0_ubuntu-latest: + name: instrumentation-flask-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-flask-0 -- -ra + + pypy3-test-instrumentation-flask-1_ubuntu-latest: + name: instrumentation-flask-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-flask-1 -- -ra + + py39-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-urllib -- -ra + + py310-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-urllib -- -ra + + py311-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-urllib -- -ra + + py312-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-urllib -- -ra + + py313-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-urllib -- -ra + + py314-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-urllib -- -ra + + pypy3-test-instrumentation-urllib_ubuntu-latest: + name: instrumentation-urllib pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-urllib -- -ra + + py39-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + + py39-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + + py310-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra + + py310-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra + + py311-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-urllib3-0 -- -ra + + py311-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-urllib3-1 -- -ra + + py312-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-urllib3-0 -- -ra + + py312-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-urllib3-1 -- -ra + + py313-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-urllib3-0 -- -ra + + py313-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-urllib3-1 -- -ra + + pypy3-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra + + pypy3-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra + + py39-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-requests -- -ra + + py310-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-requests -- -ra + + py311-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-requests -- -ra + + py312-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-requests -- -ra + + py313-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-requests -- -ra + + py314-test-instrumentation-requests_ubuntu-latest: + name: instrumentation-requests 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-requests -- -ra + + py39-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-starlette-oldest -- -ra + + py39-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-starlette-latest -- -ra + + py310-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-starlette-oldest -- -ra + + py310-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-starlette-latest -- -ra + + py311-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-starlette-oldest -- -ra + + py311-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-starlette-latest -- -ra + + py312-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-starlette-oldest -- -ra + + py312-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-starlette-latest -- -ra + + py313-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-starlette-oldest -- -ra + + py313-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-starlette-latest -- -ra + + py314-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-starlette-oldest -- -ra + + py314-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-starlette-latest -- -ra + + pypy3-test-instrumentation-starlette-oldest_ubuntu-latest: + name: instrumentation-starlette-oldest pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-starlette-oldest -- -ra + + pypy3-test-instrumentation-starlette-latest_ubuntu-latest: + name: instrumentation-starlette-latest pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-starlette-latest -- -ra + + py39-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-jinja2 -- -ra + + py310-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-jinja2 -- -ra + + py311-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-jinja2 -- -ra + + py312-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-jinja2 -- -ra + + py313-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-jinja2 -- -ra + + py314-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-jinja2 -- -ra + + pypy3-test-instrumentation-jinja2_ubuntu-latest: + name: instrumentation-jinja2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-jinja2 -- -ra + + py39-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-logging -- -ra + + py310-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-logging -- -ra + + py311-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-logging -- -ra + + py312-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-logging -- -ra + + py313-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-logging -- -ra + + py314-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-logging -- -ra + + pypy3-test-instrumentation-logging_ubuntu-latest: + name: instrumentation-logging pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-logging -- -ra + + py39-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-exporter-richconsole -- -ra + + py310-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-exporter-richconsole -- -ra + + py311-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-exporter-richconsole -- -ra + + py312-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-exporter-richconsole -- -ra + + py313-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-exporter-richconsole -- -ra + + py314-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-exporter-richconsole -- -ra + + pypy3-test-exporter-richconsole_ubuntu-latest: + name: exporter-richconsole pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-exporter-richconsole -- -ra + + py39-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-exporter-prometheus-remote-write -- -ra + + py310-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-exporter-prometheus-remote-write -- -ra + + py311-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-exporter-prometheus-remote-write -- -ra + + py312-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-exporter-prometheus-remote-write -- -ra + + py313-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-exporter-prometheus-remote-write -- -ra + + py314-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-exporter-prometheus-remote-write -- -ra + + pypy310-test-exporter-prometheus-remote-write_ubuntu-latest: + name: exporter-prometheus-remote-write pypy-3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.10 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy310-test-exporter-prometheus-remote-write -- -ra + + py39-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-mysql-0 -- -ra + + py39-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-mysql-1 -- -ra + + py310-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-mysql-0 -- -ra + + py310-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-mysql-1 -- -ra + + py311-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-mysql-0 -- -ra + + py311-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-mysql-1 -- -ra + + py312-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-mysql-0 -- -ra + + py312-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-mysql-1 -- -ra + + py313-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-mysql-0 -- -ra + + py313-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-mysql-1 -- -ra + + py314-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-mysql-0 -- -ra + + py314-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-mysql-1 -- -ra + + pypy3-test-instrumentation-mysql-0_ubuntu-latest: + name: instrumentation-mysql-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra + + pypy3-test-instrumentation-mysql-1_ubuntu-latest: + name: instrumentation-mysql-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra + + py39-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-mysqlclient -- -ra + + py310-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-mysqlclient -- -ra + + py311-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-mysqlclient -- -ra + + py312-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-mysqlclient -- -ra + + py313-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-mysqlclient -- -ra + + py314-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-mysqlclient -- -ra + + pypy3-test-instrumentation-mysqlclient_ubuntu-latest: + name: instrumentation-mysqlclient pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra + + py39-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-psycopg2 -- -ra + + py310-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-psycopg2 -- -ra + + py311-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-psycopg2 -- -ra + + py312-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-psycopg2 -- -ra + + py313-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-psycopg2 -- -ra + + py314-test-instrumentation-psycopg2_ubuntu-latest: + name: instrumentation-psycopg2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-psycopg2 -- -ra + + py39-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra + + py310-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-psycopg2-binary -- -ra + + py311-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-psycopg2-binary -- -ra + + py312-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-psycopg2-binary -- -ra + + py313-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-psycopg2-binary -- -ra + + py314-test-instrumentation-psycopg2-binary_ubuntu-latest: + name: instrumentation-psycopg2-binary 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-psycopg2-binary -- -ra + + py39-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-psycopg -- -ra + + py310-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-psycopg -- -ra + + py311-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-psycopg -- -ra + + py312-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-psycopg -- -ra + + py313-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-psycopg -- -ra + + py314-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-psycopg -- -ra + + pypy3-test-instrumentation-psycopg_ubuntu-latest: + name: instrumentation-psycopg pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-psycopg -- -ra + + py39-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + + py39-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + + py39-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra + + py39-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + + py39-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra + + py310-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra + + py310-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra + + py310-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra + + py310-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra + + py310-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra + + py311-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra + + py311-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra + + py311-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra + + py311-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra + + py311-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra + + py312-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra + + py312-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra + + py312-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra + + py312-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra + + py312-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pymemcache-4 -- -ra + + py313-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pymemcache-0 -- -ra + + py313-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pymemcache-1 -- -ra + + py313-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pymemcache-2 -- -ra + + py313-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pymemcache-3 -- -ra + + py313-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pymemcache-4 -- -ra + + py314-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pymemcache-0 -- -ra + + py314-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pymemcache-1 -- -ra + + py314-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pymemcache-2 -- -ra + + py314-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pymemcache-3 -- -ra + + py314-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pymemcache-4 -- -ra + + pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra + + pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra + + pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra + + pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: + name: instrumentation-pymemcache-3 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra + + pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: + name: instrumentation-pymemcache-4 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra + + py39-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pymongo -- -ra + + py310-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pymongo -- -ra + + py311-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pymongo -- -ra + + py312-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pymongo -- -ra + + py313-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pymongo -- -ra + + py314-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pymongo -- -ra + + pypy3-test-instrumentation-pymongo_ubuntu-latest: + name: instrumentation-pymongo pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymongo -- -ra + + py39-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pymysql -- -ra + + py310-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pymysql -- -ra + + py311-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pymysql -- -ra + + py312-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pymysql -- -ra + + py313-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pymysql -- -ra + + py314-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pymysql -- -ra + + pypy3-test-instrumentation-pymysql_ubuntu-latest: + name: instrumentation-pymysql pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pymysql -- -ra + + py39-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pymssql -- -ra + + py310-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pymssql -- -ra + + py311-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pymssql -- -ra + + py312-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pymssql -- -ra + + py313-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pymssql -- -ra + + py314-test-instrumentation-pymssql_ubuntu-latest: + name: instrumentation-pymssql 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pymssql -- -ra + + py39-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-pyramid -- -ra + + py310-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-pyramid -- -ra + + py311-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-pyramid -- -ra + + py312-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-pyramid -- -ra + + py313-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-pyramid -- -ra + + py314-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-pyramid -- -ra + + pypy3-test-instrumentation-pyramid_ubuntu-latest: + name: instrumentation-pyramid pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-pyramid -- -ra + + py39-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-asgi -- -ra + + py310-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-asgi -- -ra + + py311-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-asgi -- -ra + + py312-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-asgi -- -ra + + py313-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-asgi -- -ra + + py314-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-asgi -- -ra + + pypy3-test-instrumentation-asgi_ubuntu-latest: + name: instrumentation-asgi pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-asgi -- -ra + + py39-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-asyncpg-wrapt1 -- -ra + + py39-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-asyncpg-wrapt2 -- -ra + + py310-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-asyncpg-wrapt1 -- -ra + + py310-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-asyncpg-wrapt2 -- -ra + + py311-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-asyncpg-wrapt1 -- -ra + + py311-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-asyncpg-wrapt2 -- -ra + + py312-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-asyncpg-wrapt1 -- -ra + + py312-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-asyncpg-wrapt2 -- -ra + + py313-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-asyncpg-wrapt1 -- -ra + + py313-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-asyncpg-wrapt2 -- -ra + + py314-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: + name: instrumentation-asyncpg-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-asyncpg-wrapt1 -- -ra + + py314-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: + name: instrumentation-asyncpg-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-asyncpg-wrapt2 -- -ra + + py39-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sqlite3 -- -ra + + py310-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sqlite3 -- -ra + + py311-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-sqlite3 -- -ra + + py312-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-sqlite3 -- -ra + + py313-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-sqlite3 -- -ra + + py314-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-sqlite3 -- -ra + + pypy3-test-instrumentation-sqlite3_ubuntu-latest: + name: instrumentation-sqlite3 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra + + py39-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-wsgi -- -ra + + py310-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-wsgi -- -ra + + py311-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-wsgi -- -ra + + py312-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-wsgi -- -ra + + py313-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-wsgi -- -ra + + py314-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-wsgi -- -ra + + pypy3-test-instrumentation-wsgi_ubuntu-latest: + name: instrumentation-wsgi pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-wsgi -- -ra + + py39-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-grpc-0-wrapt1 -- -ra + + py39-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-grpc-0-wrapt2 -- -ra + + py39-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-grpc-1-wrapt1 -- -ra + + py39-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-grpc-1-wrapt2 -- -ra + + py310-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra + + py310-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra + + py310-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra + + py310-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra + + py311-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-grpc-0-wrapt1 -- -ra + + py311-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-grpc-0-wrapt2 -- -ra + + py311-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-grpc-1-wrapt1 -- -ra + + py311-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-grpc-1-wrapt2 -- -ra + + py312-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-grpc-0-wrapt1 -- -ra + + py312-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-grpc-0-wrapt2 -- -ra + + py312-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-grpc-1-wrapt1 -- -ra + + py312-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-grpc-1-wrapt2 -- -ra + + py313-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-grpc-1-wrapt1 -- -ra + + py313-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-grpc-1-wrapt2 -- -ra + + py314-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-grpc-1-wrapt1 -- -ra + + py314-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-grpc-1-wrapt2 -- -ra + + py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra + + py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra + + py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra + + py310-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra + + py311-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra + + py311-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-sqlalchemy-2 -- -ra + + py312-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra + + py312-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-sqlalchemy-2 -- -ra + + py313-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-sqlalchemy-1 -- -ra + + py313-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-sqlalchemy-2 -- -ra + + py314-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-sqlalchemy-2 -- -ra + + pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: + name: instrumentation-sqlalchemy-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra + + pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: + name: instrumentation-sqlalchemy-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra + + pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: + name: instrumentation-sqlalchemy-2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra + + py39-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-redis -- -ra + + py310-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-redis -- -ra + + py311-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-redis -- -ra + + py312-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-redis -- -ra + + py313-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-redis -- -ra + + py314-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-redis -- -ra + + pypy3-test-instrumentation-redis_ubuntu-latest: + name: instrumentation-redis pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-redis -- -ra + + py39-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-remoulade -- -ra + + py310-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-remoulade -- -ra + + py311-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-remoulade -- -ra + + py312-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-remoulade -- -ra + + py313-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-remoulade -- -ra + + py314-test-instrumentation-remoulade_ubuntu-latest: + name: instrumentation-remoulade 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-remoulade -- -ra + + py39-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-celery -- -ra + + py310-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-celery -- -ra + + py311-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-celery -- -ra + + py312-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-celery -- -ra + + py313-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-celery -- -ra + + py314-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-celery -- -ra + + pypy3-test-instrumentation-celery_ubuntu-latest: + name: instrumentation-celery pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-celery -- -ra + + py39-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-system-metrics -- -ra + + py310-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-system-metrics -- -ra + + py311-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-system-metrics -- -ra + + py312-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-system-metrics -- -ra + + py313-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-system-metrics -- -ra + + py314-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-system-metrics -- -ra + + pypy3-test-instrumentation-system-metrics_ubuntu-latest: + name: instrumentation-system-metrics pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-system-metrics -- -ra + + py39-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-threading -- -ra + + py310-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-threading -- -ra + + py311-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-threading -- -ra + + py312-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-threading -- -ra + + py313-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-threading -- -ra + + py314-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-threading -- -ra + + pypy3-test-instrumentation-threading_ubuntu-latest: + name: instrumentation-threading pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-threading -- -ra + + py39-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-tornado -- -ra + + py310-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-tornado -- -ra + + py311-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-tornado -- -ra + + py312-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-tornado -- -ra + + py313-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-tornado -- -ra + + py314-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-tornado -- -ra + + pypy3-test-instrumentation-tornado_ubuntu-latest: + name: instrumentation-tornado pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-tornado -- -ra + + py39-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-tortoiseorm -- -ra + + py310-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-tortoiseorm -- -ra + + py311-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-tortoiseorm -- -ra + + py312-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-tortoiseorm -- -ra + + py313-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-tortoiseorm -- -ra + + py314-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-tortoiseorm -- -ra + + pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: + name: instrumentation-tortoiseorm pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra + + py39-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: + name: instrumentation-httpx-0-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-httpx-0-wrapt1 -- -ra + + py39-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-httpx-0-wrapt2 -- -ra + + py39-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-httpx-1-wrapt1 -- -ra + + py39-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-httpx-1-wrapt2 -- -ra + + py310-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: + name: instrumentation-httpx-0-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-httpx-0-wrapt1 -- -ra + + py310-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-httpx-0-wrapt2 -- -ra + + py310-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-httpx-1-wrapt1 -- -ra + + py310-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-httpx-1-wrapt2 -- -ra + + py311-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: + name: instrumentation-httpx-0-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-httpx-0-wrapt1 -- -ra + + py311-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-httpx-0-wrapt2 -- -ra + + py311-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-httpx-1-wrapt1 -- -ra + + py311-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-httpx-1-wrapt2 -- -ra + + py312-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: + name: instrumentation-httpx-0-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-httpx-0-wrapt1 -- -ra + + py312-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-httpx-0-wrapt2 -- -ra + + py312-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-httpx-1-wrapt1 -- -ra + + py312-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-httpx-1-wrapt2 -- -ra + + py313-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-httpx-1-wrapt1 -- -ra + + py313-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-httpx-1-wrapt2 -- -ra + + py314-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: + name: instrumentation-httpx-1-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-httpx-1-wrapt1 -- -ra + + py314-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-httpx-1-wrapt2 -- -ra + + pypy3-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: + name: instrumentation-httpx-0-wrapt2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-httpx-0-wrapt2 -- -ra + + pypy3-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: + name: instrumentation-httpx-1-wrapt2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-httpx-1-wrapt2 -- -ra + + py39-test-util-http_ubuntu-latest: + name: util-http 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-util-http -- -ra + + py310-test-util-http_ubuntu-latest: + name: util-http 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-util-http -- -ra + + py311-test-util-http_ubuntu-latest: + name: util-http 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-util-http -- -ra + + py312-test-util-http_ubuntu-latest: + name: util-http 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-util-http -- -ra + + py313-test-util-http_ubuntu-latest: + name: util-http 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-util-http -- -ra + + py314-test-util-http_ubuntu-latest: + name: util-http 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-util-http -- -ra + + pypy3-test-util-http_ubuntu-latest: + name: util-http pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-util-http -- -ra + + py39-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-exporter-credential-provider-gcp -- -ra + + py310-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-exporter-credential-provider-gcp -- -ra + + py311-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-exporter-credential-provider-gcp -- -ra + + py312-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-exporter-credential-provider-gcp -- -ra + + py313-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-exporter-credential-provider-gcp -- -ra + + py314-test-exporter-credential-provider-gcp_ubuntu-latest: + name: exporter-credential-provider-gcp 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-exporter-credential-provider-gcp -- -ra + + py39-test-util-genai_ubuntu-latest: + name: util-genai 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-util-genai -- -ra + + py310-test-util-genai_ubuntu-latest: + name: util-genai 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-util-genai -- -ra + + py311-test-util-genai_ubuntu-latest: + name: util-genai 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-util-genai -- -ra + + py312-test-util-genai_ubuntu-latest: + name: util-genai 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-util-genai -- -ra + + py313-test-util-genai_ubuntu-latest: + name: util-genai 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-util-genai -- -ra + + py314-test-util-genai_ubuntu-latest: + name: util-genai 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-util-genai -- -ra + + pypy3-test-util-genai_ubuntu-latest: + name: util-genai pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-util-genai -- -ra + + py39-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray-0 -- -ra + + py39-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-propagator-aws-xray-1 -- -ra + + py310-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-propagator-aws-xray-0 -- -ra + + py310-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-propagator-aws-xray-1 -- -ra + + py311-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-propagator-aws-xray-0 -- -ra + + py311-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-propagator-aws-xray-1 -- -ra + + py312-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-propagator-aws-xray-0 -- -ra + + py312-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-propagator-aws-xray-1 -- -ra + + py313-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-propagator-aws-xray-0 -- -ra + + py313-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-propagator-aws-xray-1 -- -ra + + py314-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-propagator-aws-xray-0 -- -ra + + py314-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-propagator-aws-xray-1 -- -ra + + pypy3-test-propagator-aws-xray-0_ubuntu-latest: + name: propagator-aws-xray-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra + + pypy3-test-propagator-aws-xray-1_ubuntu-latest: + name: propagator-aws-xray-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra + + py39-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-propagator-ot-trace -- -ra + + py310-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-propagator-ot-trace -- -ra + + py311-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-propagator-ot-trace -- -ra + + py312-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-propagator-ot-trace -- -ra + + py313-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-propagator-ot-trace -- -ra + + py314-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-propagator-ot-trace -- -ra + + pypy3-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-propagator-ot-trace -- -ra + + py39-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-0-wrapt1 -- -ra + + py39-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + py39-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-1-wrapt1 -- -ra + + py39-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py310-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-0-wrapt1 -- -ra + + py310-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + py310-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-1-wrapt1 -- -ra + + py310-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py311-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-sio-pika-0-wrapt1 -- -ra + + py311-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + py311-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-sio-pika-1-wrapt1 -- -ra + + py311-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py312-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-sio-pika-0-wrapt1 -- -ra + + py312-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + py312-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-sio-pika-1-wrapt1 -- -ra + + py312-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py313-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-sio-pika-0-wrapt1 -- -ra + + py313-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + py313-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-sio-pika-1-wrapt1 -- -ra + + py313-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py314-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-sio-pika-0-wrapt1 -- -ra + + py314-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + py314-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-sio-pika-1-wrapt1 -- -ra + + py314-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + pypy3-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-0-wrapt2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sio-pika-0-wrapt2 -- -ra + + pypy3-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: + name: instrumentation-sio-pika-1-wrapt2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-sio-pika-1-wrapt2 -- -ra + + py39-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra + + py39-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra + + py39-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra + + py39-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra + + py310-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra + + py310-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra + + py310-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra + + py310-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra + + py311-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-0 -- -ra + + py311-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-1 -- -ra + + py311-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-2 -- -ra + + py311-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aio-pika-3 -- -ra + + py312-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-0 -- -ra + + py312-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-1 -- -ra + + py312-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-2 -- -ra + + py312-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aio-pika-3 -- -ra + + py313-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aio-pika-0 -- -ra + + py313-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aio-pika-1 -- -ra + + py313-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aio-pika-2 -- -ra + + py313-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aio-pika-3 -- -ra + + py314-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aio-pika-0 -- -ra + + py314-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aio-pika-1 -- -ra + + py314-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aio-pika-2 -- -ra + + py314-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aio-pika-3 -- -ra + + pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: + name: instrumentation-aio-pika-0 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra + + pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: + name: instrumentation-aio-pika-1 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra + + pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: + name: instrumentation-aio-pika-2 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra + + pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: + name: instrumentation-aio-pika-3 pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra + + py39-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-aiokafka -- -ra + + py310-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-aiokafka -- -ra + + py311-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-aiokafka -- -ra + + py312-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-aiokafka -- -ra + + py313-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-aiokafka -- -ra + + py314-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-aiokafka -- -ra + + pypy3-test-instrumentation-aiokafka_ubuntu-latest: + name: instrumentation-aiokafka pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-aiokafka -- -ra + + py39-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-kafka-python -- -ra + + py310-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-kafka-python -- -ra + + py311-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-kafka-python -- -ra + + py39-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra + + py310-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra + + py311-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-kafka-pythonng -- -ra + + py312-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-kafka-pythonng -- -ra + + py313-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-kafka-pythonng -- -ra + + py314-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-kafka-pythonng -- -ra + + pypy3-test-instrumentation-kafka-python_ubuntu-latest: + name: instrumentation-kafka-python pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-kafka-python -- -ra + + pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: + name: instrumentation-kafka-pythonng pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra + + py39-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-confluent-kafka -- -ra + + py310-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-confluent-kafka -- -ra + + py311-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-confluent-kafka -- -ra + + py312-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-confluent-kafka -- -ra + + py313-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-confluent-kafka -- -ra + + py314-test-instrumentation-confluent-kafka_ubuntu-latest: + name: instrumentation-confluent-kafka 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-confluent-kafka -- -ra + + py39-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-asyncio -- -ra + + py310-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-asyncio -- -ra + + py311-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-asyncio -- -ra + + py312-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-asyncio -- -ra + + py313-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-asyncio -- -ra + + py314-test-instrumentation-asyncio_ubuntu-latest: + name: instrumentation-asyncio 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-asyncio -- -ra + + py39-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-cassandra-driver -- -ra + + py39-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-instrumentation-cassandra-scylla -- -ra + + py310-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-cassandra-driver -- -ra + + py310-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-cassandra-scylla -- -ra + + py311-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-cassandra-driver -- -ra + + py311-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-cassandra-scylla -- -ra + + py312-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-cassandra-driver -- -ra + + py312-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-cassandra-scylla -- -ra + + py313-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-cassandra-driver -- -ra + + py313-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-cassandra-scylla -- -ra + + py314-test-instrumentation-cassandra-driver_ubuntu-latest: + name: instrumentation-cassandra-driver 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-cassandra-driver -- -ra + + py314-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra + + pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: + name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra + + py39-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-processor-baggage -- -ra + + py310-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-processor-baggage -- -ra + + py311-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-processor-baggage -- -ra + + py312-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-processor-baggage -- -ra + + py313-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-processor-baggage -- -ra + + py314-test-processor-baggage_ubuntu-latest: + name: processor-baggage 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-processor-baggage -- -ra + + pypy3-test-processor-baggage_ubuntu-latest: + name: processor-baggage pypy-3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python pypy-3.9 + uses: actions/setup-python@v5 + with: + python-version: "pypy-3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e pypy3-test-processor-baggage -- -ra + + py39-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opamp-client-latest -- -ra + + py39-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.9 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py39-test-opamp-client-lowest -- -ra + + py310-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opamp-client-latest -- -ra + + py310-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.10 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-opamp-client-lowest -- -ra + + py311-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opamp-client-latest -- -ra + + py311-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-opamp-client-lowest -- -ra + + py312-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opamp-client-latest -- -ra + + py312-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-opamp-client-lowest -- -ra + + py313-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opamp-client-latest -- -ra + + py313-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-opamp-client-lowest -- -ra + + py314-test-opamp-client-latest_ubuntu-latest: + name: opamp-client-latest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opamp-client-latest -- -ra + + py314-test-opamp-client-lowest_ubuntu-latest: + name: opamp-client-lowest 3.14 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.14 + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py314-test-opamp-client-lowest -- -ra diff --git a/.github/workflows/test_0.yml b/.github/workflows/test_0.yml deleted file mode 100644 index fd5a9c4fab3..00000000000 --- a/.github/workflows/test_0.yml +++ /dev/null @@ -1,4782 +0,0 @@ -# Do not edit this file. -# This file is generated automatically by executing tox -e generate-workflows - -name: Test 0 - -on: - push: - branches: - - 'main' - pull_request: - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -env: - # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' - # For PRs you can change the inner fallback ('main') - # For pushes you change the outer fallback ('main') - # The logic below is used during releases and depends on having an equivalent branch name in the core repo. - CORE_REPO_SHA: ${{ github.event_name == 'pull_request' && ( - contains(github.event.pull_request.labels.*.name, 'prepare-release') && github.event.pull_request.head.ref || - contains(github.event.pull_request.labels.*.name, 'backport') && github.event.pull_request.base.ref || - 'main' - ) || 'main' }} - CONTRIB_REPO_SHA: main - PIP_EXISTS_ACTION: w - -jobs: - - py39-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-oldest -- -ra - - py39-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-latest -- -ra - - py310-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-openai-v2-oldest -- -ra - - py310-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-openai-v2-latest -- -ra - - py311-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-openai-v2-oldest -- -ra - - py311-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-openai-v2-latest -- -ra - - py312-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-openai-v2-oldest -- -ra - - py312-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-openai-v2-latest -- -ra - - py313-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-openai-v2-oldest -- -ra - - py313-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-openai-v2-latest -- -ra - - py314-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-openai-v2-oldest -- -ra - - py314-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-openai-v2-latest -- -ra - - pypy3-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-openai-v2-oldest -- -ra - - pypy3-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-openai-v2-latest -- -ra - - py310-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: - name: instrumentation-openai_agents-v2-oldest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-openai_agents-v2-oldest -- -ra - - py310-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: - name: instrumentation-openai_agents-v2-latest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-openai_agents-v2-latest -- -ra - - py311-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: - name: instrumentation-openai_agents-v2-oldest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-openai_agents-v2-oldest -- -ra - - py311-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: - name: instrumentation-openai_agents-v2-latest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-openai_agents-v2-latest -- -ra - - py312-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: - name: instrumentation-openai_agents-v2-oldest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-openai_agents-v2-oldest -- -ra - - py312-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: - name: instrumentation-openai_agents-v2-latest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-openai_agents-v2-latest -- -ra - - py313-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: - name: instrumentation-openai_agents-v2-oldest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-openai_agents-v2-oldest -- -ra - - py313-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: - name: instrumentation-openai_agents-v2-latest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-openai_agents-v2-latest -- -ra - - py314-test-instrumentation-openai_agents-v2-oldest_ubuntu-latest: - name: instrumentation-openai_agents-v2-oldest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-openai_agents-v2-oldest -- -ra - - py314-test-instrumentation-openai_agents-v2-latest_ubuntu-latest: - name: instrumentation-openai_agents-v2-latest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-openai_agents-v2-latest -- -ra - - py39-test-instrumentation-vertexai-oldest_ubuntu-latest: - name: instrumentation-vertexai-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-oldest -- -ra - - py39-test-instrumentation-vertexai-latest_ubuntu-latest: - name: instrumentation-vertexai-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-latest -- -ra - - py310-test-instrumentation-vertexai-oldest_ubuntu-latest: - name: instrumentation-vertexai-oldest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-vertexai-oldest -- -ra - - py310-test-instrumentation-vertexai-latest_ubuntu-latest: - name: instrumentation-vertexai-latest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-vertexai-latest -- -ra - - py311-test-instrumentation-vertexai-oldest_ubuntu-latest: - name: instrumentation-vertexai-oldest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-vertexai-oldest -- -ra - - py311-test-instrumentation-vertexai-latest_ubuntu-latest: - name: instrumentation-vertexai-latest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-vertexai-latest -- -ra - - py312-test-instrumentation-vertexai-oldest_ubuntu-latest: - name: instrumentation-vertexai-oldest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-vertexai-oldest -- -ra - - py312-test-instrumentation-vertexai-latest_ubuntu-latest: - name: instrumentation-vertexai-latest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-vertexai-latest -- -ra - - py313-test-instrumentation-vertexai-oldest_ubuntu-latest: - name: instrumentation-vertexai-oldest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-vertexai-oldest -- -ra - - py313-test-instrumentation-vertexai-latest_ubuntu-latest: - name: instrumentation-vertexai-latest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-vertexai-latest -- -ra - - py314-test-instrumentation-vertexai-oldest_ubuntu-latest: - name: instrumentation-vertexai-oldest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-vertexai-oldest -- -ra - - py314-test-instrumentation-vertexai-latest_ubuntu-latest: - name: instrumentation-vertexai-latest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-vertexai-latest -- -ra - - py39-test-instrumentation-google-genai-oldest_ubuntu-latest: - name: instrumentation-google-genai-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-oldest -- -ra - - py39-test-instrumentation-google-genai-latest_ubuntu-latest: - name: instrumentation-google-genai-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-latest -- -ra - - py310-test-instrumentation-google-genai-oldest_ubuntu-latest: - name: instrumentation-google-genai-oldest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-google-genai-oldest -- -ra - - py310-test-instrumentation-google-genai-latest_ubuntu-latest: - name: instrumentation-google-genai-latest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-google-genai-latest -- -ra - - py311-test-instrumentation-google-genai-oldest_ubuntu-latest: - name: instrumentation-google-genai-oldest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-google-genai-oldest -- -ra - - py311-test-instrumentation-google-genai-latest_ubuntu-latest: - name: instrumentation-google-genai-latest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-google-genai-latest -- -ra - - py312-test-instrumentation-google-genai-oldest_ubuntu-latest: - name: instrumentation-google-genai-oldest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-google-genai-oldest -- -ra - - py312-test-instrumentation-google-genai-latest_ubuntu-latest: - name: instrumentation-google-genai-latest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-google-genai-latest -- -ra - - py313-test-instrumentation-google-genai-oldest_ubuntu-latest: - name: instrumentation-google-genai-oldest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-google-genai-oldest -- -ra - - py313-test-instrumentation-google-genai-latest_ubuntu-latest: - name: instrumentation-google-genai-latest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-google-genai-latest -- -ra - - py314-test-instrumentation-google-genai-oldest_ubuntu-latest: - name: instrumentation-google-genai-oldest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-google-genai-oldest -- -ra - - py314-test-instrumentation-google-genai-latest_ubuntu-latest: - name: instrumentation-google-genai-latest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-google-genai-latest -- -ra - - py39-test-instrumentation-anthropic-oldest_ubuntu-latest: - name: instrumentation-anthropic-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-oldest -- -ra - - py39-test-instrumentation-anthropic-latest_ubuntu-latest: - name: instrumentation-anthropic-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-latest -- -ra - - py310-test-instrumentation-anthropic-oldest_ubuntu-latest: - name: instrumentation-anthropic-oldest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-anthropic-oldest -- -ra - - py310-test-instrumentation-anthropic-latest_ubuntu-latest: - name: instrumentation-anthropic-latest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-anthropic-latest -- -ra - - py311-test-instrumentation-anthropic-oldest_ubuntu-latest: - name: instrumentation-anthropic-oldest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-anthropic-oldest -- -ra - - py311-test-instrumentation-anthropic-latest_ubuntu-latest: - name: instrumentation-anthropic-latest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-anthropic-latest -- -ra - - py312-test-instrumentation-anthropic-oldest_ubuntu-latest: - name: instrumentation-anthropic-oldest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-anthropic-oldest -- -ra - - py312-test-instrumentation-anthropic-latest_ubuntu-latest: - name: instrumentation-anthropic-latest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-anthropic-latest -- -ra - - py313-test-instrumentation-anthropic-oldest_ubuntu-latest: - name: instrumentation-anthropic-oldest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-anthropic-oldest -- -ra - - py313-test-instrumentation-anthropic-latest_ubuntu-latest: - name: instrumentation-anthropic-latest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-anthropic-latest -- -ra - - py314-test-instrumentation-anthropic-oldest_ubuntu-latest: - name: instrumentation-anthropic-oldest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-anthropic-oldest -- -ra - - py314-test-instrumentation-anthropic-latest_ubuntu-latest: - name: instrumentation-anthropic-latest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-anthropic-latest -- -ra - - py310-test-instrumentation-claude-agent-sdk-oldest_ubuntu-latest: - name: instrumentation-claude-agent-sdk-oldest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-claude-agent-sdk-oldest -- -ra - - py310-test-instrumentation-claude-agent-sdk-latest_ubuntu-latest: - name: instrumentation-claude-agent-sdk-latest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-claude-agent-sdk-latest -- -ra - - py311-test-instrumentation-claude-agent-sdk-oldest_ubuntu-latest: - name: instrumentation-claude-agent-sdk-oldest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-claude-agent-sdk-oldest -- -ra - - py311-test-instrumentation-claude-agent-sdk-latest_ubuntu-latest: - name: instrumentation-claude-agent-sdk-latest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-claude-agent-sdk-latest -- -ra - - py312-test-instrumentation-claude-agent-sdk-oldest_ubuntu-latest: - name: instrumentation-claude-agent-sdk-oldest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-claude-agent-sdk-oldest -- -ra - - py312-test-instrumentation-claude-agent-sdk-latest_ubuntu-latest: - name: instrumentation-claude-agent-sdk-latest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-claude-agent-sdk-latest -- -ra - - py313-test-instrumentation-claude-agent-sdk-oldest_ubuntu-latest: - name: instrumentation-claude-agent-sdk-oldest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-claude-agent-sdk-oldest -- -ra - - py313-test-instrumentation-claude-agent-sdk-latest_ubuntu-latest: - name: instrumentation-claude-agent-sdk-latest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-claude-agent-sdk-latest -- -ra - - py39-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-containerid -- -ra - - py310-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-resource-detector-containerid -- -ra - - py311-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-resource-detector-containerid -- -ra - - py312-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-resource-detector-containerid -- -ra - - py313-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-resource-detector-containerid -- -ra - - py314-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-resource-detector-containerid -- -ra - - pypy3-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-resource-detector-containerid -- -ra - - py39-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-azure-0 -- -ra - - py39-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-azure-1 -- -ra - - py310-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-resource-detector-azure-0 -- -ra - - py310-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-resource-detector-azure-1 -- -ra - - py311-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-resource-detector-azure-0 -- -ra - - py311-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-resource-detector-azure-1 -- -ra - - py312-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-resource-detector-azure-0 -- -ra - - py312-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-resource-detector-azure-1 -- -ra - - py313-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-resource-detector-azure-0 -- -ra - - py313-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-resource-detector-azure-1 -- -ra - - py314-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-resource-detector-azure-0 -- -ra - - py314-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-resource-detector-azure-1 -- -ra - - pypy3-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-resource-detector-azure-0 -- -ra - - pypy3-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-resource-detector-azure-1 -- -ra - - py39-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-sdk-extension-aws-0 -- -ra - - py39-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-sdk-extension-aws-1 -- -ra - - py310-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-sdk-extension-aws-0 -- -ra - - py310-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-sdk-extension-aws-1 -- -ra - - py311-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-sdk-extension-aws-0 -- -ra - - py311-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-sdk-extension-aws-1 -- -ra - - py312-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-sdk-extension-aws-0 -- -ra - - py312-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-sdk-extension-aws-1 -- -ra - - py313-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-sdk-extension-aws-0 -- -ra - - py313-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-sdk-extension-aws-1 -- -ra - - py314-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-sdk-extension-aws-0 -- -ra - - py314-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-sdk-extension-aws-1 -- -ra - - pypy3-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-sdk-extension-aws-0 -- -ra - - pypy3-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-sdk-extension-aws-1 -- -ra - - py39-test-distro_ubuntu-latest: - name: distro 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-distro -- -ra - - py310-test-distro_ubuntu-latest: - name: distro 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-distro -- -ra - - py311-test-distro_ubuntu-latest: - name: distro 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-distro -- -ra - - py312-test-distro_ubuntu-latest: - name: distro 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-distro -- -ra - - py313-test-distro_ubuntu-latest: - name: distro 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-distro -- -ra - - py314-test-distro_ubuntu-latest: - name: distro 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-distro -- -ra - - pypy3-test-distro_ubuntu-latest: - name: distro pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-distro -- -ra - - py39-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt1 -- -ra - - py39-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt2 -- -ra - - py310-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-opentelemetry-instrumentation-wrapt1 -- -ra - - py310-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-opentelemetry-instrumentation-wrapt2 -- -ra - - py311-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-opentelemetry-instrumentation-wrapt1 -- -ra - - py311-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-opentelemetry-instrumentation-wrapt2 -- -ra - - py312-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-opentelemetry-instrumentation-wrapt1 -- -ra - - py312-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-opentelemetry-instrumentation-wrapt2 -- -ra - - py313-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-opentelemetry-instrumentation-wrapt1 -- -ra - - py313-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-opentelemetry-instrumentation-wrapt2 -- -ra - - py314-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-opentelemetry-instrumentation-wrapt1 -- -ra - - py314-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-opentelemetry-instrumentation-wrapt2 -- -ra - - pypy3-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-opentelemetry-instrumentation-wrapt2 -- -ra - - py39-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-client -- -ra - - py310-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aiohttp-client -- -ra - - py311-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aiohttp-client -- -ra - - py312-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aiohttp-client -- -ra - - py313-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aiohttp-client -- -ra - - py314-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aiohttp-client -- -ra - - pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-aiohttp-client -- -ra - - py39-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-server -- -ra - - py310-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aiohttp-server -- -ra - - py311-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aiohttp-server -- -ra - - py312-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aiohttp-server -- -ra - - py313-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aiohttp-server -- -ra - - py314-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aiohttp-server -- -ra - - pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra - - py39-test-instrumentation-aiopg-wrapt1_ubuntu-latest: - name: instrumentation-aiopg-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt1 -- -ra - - py39-test-instrumentation-aiopg-wrapt2_ubuntu-latest: - name: instrumentation-aiopg-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt2 -- -ra - - py310-test-instrumentation-aiopg-wrapt1_ubuntu-latest: - name: instrumentation-aiopg-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aiopg-wrapt1 -- -ra - - py310-test-instrumentation-aiopg-wrapt2_ubuntu-latest: - name: instrumentation-aiopg-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aiopg-wrapt2 -- -ra - - py311-test-instrumentation-aiopg-wrapt1_ubuntu-latest: - name: instrumentation-aiopg-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aiopg-wrapt1 -- -ra - - py311-test-instrumentation-aiopg-wrapt2_ubuntu-latest: - name: instrumentation-aiopg-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aiopg-wrapt2 -- -ra - - py312-test-instrumentation-aiopg-wrapt1_ubuntu-latest: - name: instrumentation-aiopg-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aiopg-wrapt1 -- -ra - - py312-test-instrumentation-aiopg-wrapt2_ubuntu-latest: - name: instrumentation-aiopg-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aiopg-wrapt2 -- -ra - - py313-test-instrumentation-aiopg-wrapt1_ubuntu-latest: - name: instrumentation-aiopg-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aiopg-wrapt1 -- -ra - - py313-test-instrumentation-aiopg-wrapt2_ubuntu-latest: - name: instrumentation-aiopg-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aiopg-wrapt2 -- -ra - - py314-test-instrumentation-aiopg-wrapt1_ubuntu-latest: - name: instrumentation-aiopg-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aiopg-wrapt1 -- -ra - - py314-test-instrumentation-aiopg-wrapt2_ubuntu-latest: - name: instrumentation-aiopg-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aiopg-wrapt2 -- -ra - - py39-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aws-lambda -- -ra - - py310-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aws-lambda -- -ra - - py311-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aws-lambda -- -ra - - py312-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aws-lambda -- -ra - - py313-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aws-lambda -- -ra - - py314-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aws-lambda -- -ra - - pypy3-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra - - py39-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: - name: instrumentation-botocore-0-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt1 -- -ra - - py39-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: - name: instrumentation-botocore-0-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt2 -- -ra - - py39-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: - name: instrumentation-botocore-1-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt1 -- -ra - - py39-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: - name: instrumentation-botocore-1-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra - - py310-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: - name: instrumentation-botocore-0-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-botocore-0-wrapt1 -- -ra - - py310-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: - name: instrumentation-botocore-0-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-botocore-0-wrapt2 -- -ra - - py310-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: - name: instrumentation-botocore-1-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-botocore-1-wrapt1 -- -ra - - py310-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: - name: instrumentation-botocore-1-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-botocore-1-wrapt2 -- -ra - - py311-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: - name: instrumentation-botocore-0-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-botocore-0-wrapt1 -- -ra - - py311-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: - name: instrumentation-botocore-0-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-botocore-0-wrapt2 -- -ra - - py311-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: - name: instrumentation-botocore-1-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-botocore-1-wrapt1 -- -ra - - py311-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: - name: instrumentation-botocore-1-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-botocore-1-wrapt2 -- -ra - - py312-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: - name: instrumentation-botocore-0-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-botocore-0-wrapt1 -- -ra - - py312-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: - name: instrumentation-botocore-0-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-botocore-0-wrapt2 -- -ra - - py312-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: - name: instrumentation-botocore-1-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-botocore-1-wrapt1 -- -ra - - py312-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: - name: instrumentation-botocore-1-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-botocore-1-wrapt2 -- -ra - - py313-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: - name: instrumentation-botocore-0-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-botocore-0-wrapt1 -- -ra - - py313-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: - name: instrumentation-botocore-0-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-botocore-0-wrapt2 -- -ra - - py313-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: - name: instrumentation-botocore-1-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-botocore-1-wrapt1 -- -ra - - py313-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: - name: instrumentation-botocore-1-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-botocore-1-wrapt2 -- -ra - - py314-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: - name: instrumentation-botocore-0-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-botocore-0-wrapt1 -- -ra - - py314-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: - name: instrumentation-botocore-0-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-botocore-0-wrapt2 -- -ra - - py314-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: - name: instrumentation-botocore-1-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-botocore-1-wrapt1 -- -ra - - py314-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: - name: instrumentation-botocore-1-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-botocore-1-wrapt2 -- -ra - - py39-test-instrumentation-botocore-2_ubuntu-latest: - name: instrumentation-botocore-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-2 -- -ra - - py39-test-instrumentation-botocore-3_ubuntu-latest: - name: instrumentation-botocore-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-3 -- -ra - - py310-test-instrumentation-botocore-2_ubuntu-latest: - name: instrumentation-botocore-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-botocore-2 -- -ra - - py310-test-instrumentation-botocore-3_ubuntu-latest: - name: instrumentation-botocore-3 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-botocore-3 -- -ra - - py311-test-instrumentation-botocore-2_ubuntu-latest: - name: instrumentation-botocore-2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-botocore-2 -- -ra - - py311-test-instrumentation-botocore-3_ubuntu-latest: - name: instrumentation-botocore-3 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-botocore-3 -- -ra - - py312-test-instrumentation-botocore-2_ubuntu-latest: - name: instrumentation-botocore-2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-botocore-2 -- -ra - - py312-test-instrumentation-botocore-3_ubuntu-latest: - name: instrumentation-botocore-3 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-botocore-3 -- -ra - - py313-test-instrumentation-botocore-2_ubuntu-latest: - name: instrumentation-botocore-2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-botocore-2 -- -ra - - py313-test-instrumentation-botocore-3_ubuntu-latest: - name: instrumentation-botocore-3 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-botocore-3 -- -ra - - py314-test-instrumentation-botocore-2_ubuntu-latest: - name: instrumentation-botocore-2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-botocore-2 -- -ra - - py314-test-instrumentation-botocore-3_ubuntu-latest: - name: instrumentation-botocore-3 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-botocore-3 -- -ra - - py39-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-boto3sqs -- -ra - - py310-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-boto3sqs -- -ra - - py311-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-boto3sqs -- -ra - - py312-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-boto3sqs -- -ra - - py313-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-boto3sqs -- -ra - - py314-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-boto3sqs -- -ra - - pypy3-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra - - py39-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-django-0 -- -ra - - py39-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-django-1 -- -ra - - py39-test-instrumentation-django-2_ubuntu-latest: - name: instrumentation-django-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-django-2 -- -ra - - py310-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-django-1 -- -ra - - py310-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-django-3 -- -ra - - py311-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-django-1 -- -ra - - py311-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-django-3 -- -ra - - py312-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-django-1 -- -ra - - py312-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-django-3 -- -ra - - py313-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-django-3 -- -ra - - py314-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-django-3 -- -ra - - pypy3-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-django-0 -- -ra - - pypy3-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-django-1 -- -ra - - py39-test-instrumentation-dbapi-wrapt1_ubuntu-latest: - name: instrumentation-dbapi-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt1 -- -ra - - py39-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra - - py310-test-instrumentation-dbapi-wrapt1_ubuntu-latest: - name: instrumentation-dbapi-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-dbapi-wrapt1 -- -ra - - py310-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-dbapi-wrapt2 -- -ra - - py311-test-instrumentation-dbapi-wrapt1_ubuntu-latest: - name: instrumentation-dbapi-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-dbapi-wrapt1 -- -ra - - py311-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-dbapi-wrapt2 -- -ra - - py312-test-instrumentation-dbapi-wrapt1_ubuntu-latest: - name: instrumentation-dbapi-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-dbapi-wrapt1 -- -ra - - py312-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-dbapi-wrapt2 -- -ra - - py313-test-instrumentation-dbapi-wrapt1_ubuntu-latest: - name: instrumentation-dbapi-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-dbapi-wrapt1 -- -ra - - py313-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-dbapi-wrapt2 -- -ra - - py314-test-instrumentation-dbapi-wrapt1_ubuntu-latest: - name: instrumentation-dbapi-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-dbapi-wrapt1 -- -ra - - py314-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-dbapi-wrapt2 -- -ra - - pypy3-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-dbapi-wrapt2 -- -ra - - py39-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncclick -- -ra - - py310-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-asyncclick -- -ra - - py311-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-asyncclick -- -ra - - py312-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-asyncclick -- -ra - - py313-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-asyncclick -- -ra - - py314-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-asyncclick -- -ra - - pypy3-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-asyncclick -- -ra - - py39-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-click -- -ra - - py310-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-click -- -ra - - py311-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-click -- -ra - - py312-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-click -- -ra - - py313-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-click -- -ra - - py314-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-click -- -ra - - pypy3-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-click -- -ra - - py39-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra - - py39-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra - - py39-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra - - py310-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra - - py310-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra - - py310-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra - - py311-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-0 -- -ra - - py311-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-1 -- -ra - - py311-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-elasticsearch-2 -- -ra - - py312-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-0 -- -ra - - py312-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-1 -- -ra diff --git a/.github/workflows/test_1.yml b/.github/workflows/test_1.yml deleted file mode 100644 index 1b0cd014d7e..00000000000 --- a/.github/workflows/test_1.yml +++ /dev/null @@ -1,4782 +0,0 @@ -# Do not edit this file. -# This file is generated automatically by executing tox -e generate-workflows - -name: Test 1 - -on: - push: - branches: - - 'main' - pull_request: - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -env: - # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' - # For PRs you can change the inner fallback ('main') - # For pushes you change the outer fallback ('main') - # The logic below is used during releases and depends on having an equivalent branch name in the core repo. - CORE_REPO_SHA: ${{ github.event_name == 'pull_request' && ( - contains(github.event.pull_request.labels.*.name, 'prepare-release') && github.event.pull_request.head.ref || - contains(github.event.pull_request.labels.*.name, 'backport') && github.event.pull_request.base.ref || - 'main' - ) || 'main' }} - CONTRIB_REPO_SHA: main - PIP_EXISTS_ACTION: w - -jobs: - - py312-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-elasticsearch-2 -- -ra - - py313-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-0 -- -ra - - py313-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-1 -- -ra - - py313-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-elasticsearch-2 -- -ra - - py314-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-0 -- -ra - - py314-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-1 -- -ra - - py314-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-elasticsearch-2 -- -ra - - pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra - - pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra - - pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra - - py39-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra - - py39-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra - - py39-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-2 -- -ra - - py39-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-3 -- -ra - - py310-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-falcon-1 -- -ra - - py310-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-falcon-2 -- -ra - - py310-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-falcon-3 -- -ra - - py310-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-falcon-4 -- -ra - - py311-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-falcon-1 -- -ra - - py311-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-falcon-2 -- -ra - - py311-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-falcon-3 -- -ra - - py311-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-falcon-4 -- -ra - - py312-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-falcon-1 -- -ra - - py312-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-falcon-2 -- -ra - - py312-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-falcon-3 -- -ra - - py312-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-falcon-4 -- -ra - - py313-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-falcon-4 -- -ra - - py314-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-falcon-4 -- -ra - - pypy3-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra - - pypy3-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra - - pypy3-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra - - pypy3-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-3 -- -ra - - pypy3-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-4 -- -ra - - py39-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-fastapi -- -ra - - py310-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-fastapi -- -ra - - py311-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-fastapi -- -ra - - py312-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-fastapi -- -ra - - py313-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-fastapi -- -ra - - py314-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-fastapi -- -ra - - pypy3-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-fastapi -- -ra - - py39-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-0 -- -ra - - py39-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-1 -- -ra - - py39-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-2 -- -ra - - py39-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-3 -- -ra - - py310-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-flask-0 -- -ra - - py310-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-flask-1 -- -ra - - py310-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-flask-2 -- -ra - - py310-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-flask-3 -- -ra - - py311-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-flask-0 -- -ra - - py311-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-flask-1 -- -ra - - py311-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-flask-2 -- -ra - - py311-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-flask-3 -- -ra - - py312-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-flask-0 -- -ra - - py312-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-flask-1 -- -ra - - py312-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-flask-2 -- -ra - - py312-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-flask-3 -- -ra - - py313-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-flask-0 -- -ra - - py313-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-flask-1 -- -ra - - py313-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-flask-2 -- -ra - - py313-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-flask-3 -- -ra - - py314-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-flask-0 -- -ra - - py314-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-flask-1 -- -ra - - py314-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-flask-2 -- -ra - - py314-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-flask-3 -- -ra - - pypy3-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-flask-0 -- -ra - - pypy3-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-flask-1 -- -ra - - py39-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-urllib -- -ra - - py310-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-urllib -- -ra - - py311-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-urllib -- -ra - - py312-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-urllib -- -ra - - py313-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-urllib -- -ra - - py314-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-urllib -- -ra - - pypy3-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib -- -ra - - py39-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-0 -- -ra - - py39-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-1 -- -ra - - py310-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - - py310-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - - py311-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-0 -- -ra - - py311-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-1 -- -ra - - py312-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-urllib3-0 -- -ra - - py312-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-urllib3-1 -- -ra - - py313-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-urllib3-0 -- -ra - - py313-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-urllib3-1 -- -ra - - pypy3-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra - - pypy3-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra - - py39-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-requests -- -ra - - py310-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-requests -- -ra - - py311-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-requests -- -ra - - py312-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-requests -- -ra - - py313-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-requests -- -ra - - py314-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-requests -- -ra - - py39-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-starlette-oldest -- -ra - - py39-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-starlette-latest -- -ra - - py310-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-starlette-oldest -- -ra - - py310-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-starlette-latest -- -ra - - py311-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-starlette-oldest -- -ra - - py311-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-starlette-latest -- -ra - - py312-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-starlette-oldest -- -ra - - py312-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-starlette-latest -- -ra - - py313-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-starlette-oldest -- -ra - - py313-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-starlette-latest -- -ra - - py314-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-starlette-oldest -- -ra - - py314-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-starlette-latest -- -ra - - pypy3-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-starlette-oldest -- -ra - - pypy3-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-starlette-latest -- -ra - - py39-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-jinja2 -- -ra - - py310-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-jinja2 -- -ra - - py311-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-jinja2 -- -ra - - py312-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-jinja2 -- -ra - - py313-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-jinja2 -- -ra - - py314-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-jinja2 -- -ra - - pypy3-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-jinja2 -- -ra - - py39-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-logging -- -ra - - py310-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-logging -- -ra - - py311-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-logging -- -ra - - py312-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-logging -- -ra - - py313-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-logging -- -ra - - py314-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-logging -- -ra - - pypy3-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-logging -- -ra - - py39-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-richconsole -- -ra - - py310-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-exporter-richconsole -- -ra - - py311-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-exporter-richconsole -- -ra - - py312-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-exporter-richconsole -- -ra - - py313-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-exporter-richconsole -- -ra - - py314-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-exporter-richconsole -- -ra - - pypy3-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-exporter-richconsole -- -ra - - py39-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-prometheus-remote-write -- -ra - - py310-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-exporter-prometheus-remote-write -- -ra - - py311-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-exporter-prometheus-remote-write -- -ra - - py312-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-exporter-prometheus-remote-write -- -ra - - py313-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-exporter-prometheus-remote-write -- -ra - - py314-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-exporter-prometheus-remote-write -- -ra - - pypy310-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write pypy-3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.10 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy310-test-exporter-prometheus-remote-write -- -ra - - py39-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysql-0 -- -ra - - py39-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra - - py310-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-mysql-0 -- -ra - - py310-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-mysql-1 -- -ra - - py311-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-mysql-0 -- -ra - - py311-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-mysql-1 -- -ra - - py312-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-mysql-0 -- -ra - - py312-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-mysql-1 -- -ra - - py313-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-mysql-0 -- -ra - - py313-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-mysql-1 -- -ra - - py314-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-mysql-0 -- -ra - - py314-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-mysql-1 -- -ra - - pypy3-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra - - pypy3-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra - - py39-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra - - py310-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-mysqlclient -- -ra - - py311-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-mysqlclient -- -ra - - py312-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-mysqlclient -- -ra - - py313-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-mysqlclient -- -ra - - py314-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-mysqlclient -- -ra - - pypy3-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra - - py39-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra - - py310-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-psycopg2 -- -ra - - py311-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-psycopg2 -- -ra - - py312-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-psycopg2 -- -ra - - py313-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-psycopg2 -- -ra - - py314-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-psycopg2 -- -ra - - py39-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra - - py310-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-psycopg2-binary -- -ra - - py311-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-psycopg2-binary -- -ra - - py312-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-psycopg2-binary -- -ra - - py313-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-psycopg2-binary -- -ra - - py314-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-psycopg2-binary -- -ra - - py39-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra - - py310-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-psycopg -- -ra - - py311-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-psycopg -- -ra - - py312-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-psycopg -- -ra - - py313-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-psycopg -- -ra - - py314-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-psycopg -- -ra - - pypy3-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-psycopg -- -ra - - py39-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra - - py39-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra - - py39-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra - - py39-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra - - py39-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra - - py310-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - - py310-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - - py310-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra - - py310-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra - - py310-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra - - py311-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-0 -- -ra - - py311-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-1 -- -ra - - py311-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-2 -- -ra - - py311-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-3 -- -ra - - py311-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pymemcache-4 -- -ra - - py312-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-0 -- -ra - - py312-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-1 -- -ra - - py312-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-2 -- -ra - - py312-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-3 -- -ra - - py312-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pymemcache-4 -- -ra - - py313-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-0 -- -ra - - py313-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-1 -- -ra - - py313-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-2 -- -ra - - py313-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-3 -- -ra - - py313-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pymemcache-4 -- -ra - - py314-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-0 -- -ra - - py314-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-1 -- -ra - - py314-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-2 -- -ra - - py314-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-3 -- -ra - - py314-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pymemcache-4 -- -ra - - pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra - - pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra - - pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra - - pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra - - pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra - - py39-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymongo -- -ra - - py310-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymongo -- -ra - - py311-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pymongo -- -ra - - py312-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pymongo -- -ra - - py313-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pymongo -- -ra - - py314-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pymongo -- -ra - - pypy3-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-pymongo -- -ra - - py39-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymysql -- -ra - - py310-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymysql -- -ra - - py311-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pymysql -- -ra - - py312-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pymysql -- -ra - - py313-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pymysql -- -ra - - py314-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pymysql -- -ra - - pypy3-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-pymysql -- -ra - - py39-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymssql -- -ra - - py310-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymssql -- -ra - - py311-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pymssql -- -ra - - py312-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pymssql -- -ra - - py313-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pymssql -- -ra - - py314-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pymssql -- -ra - - py39-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pyramid -- -ra - - py310-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pyramid -- -ra - - py311-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-pyramid -- -ra - - py312-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-pyramid -- -ra - - py313-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-pyramid -- -ra - - py314-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-pyramid -- -ra - - pypy3-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-pyramid -- -ra - - py39-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asgi -- -ra - - py310-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-asgi -- -ra - - py311-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-asgi -- -ra - - py312-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-asgi -- -ra - - py313-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-asgi -- -ra - - py314-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-asgi -- -ra - - pypy3-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-asgi -- -ra - - py39-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt1 -- -ra - - py39-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt2 -- -ra - - py310-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-asyncpg-wrapt1 -- -ra - - py310-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-asyncpg-wrapt2 -- -ra - - py311-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-asyncpg-wrapt1 -- -ra - - py311-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-asyncpg-wrapt2 -- -ra - - py312-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-asyncpg-wrapt1 -- -ra - - py312-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-asyncpg-wrapt2 -- -ra diff --git a/.github/workflows/test_2.yml b/.github/workflows/test_2.yml deleted file mode 100644 index 00c4a1a0a6e..00000000000 --- a/.github/workflows/test_2.yml +++ /dev/null @@ -1,4782 +0,0 @@ -# Do not edit this file. -# This file is generated automatically by executing tox -e generate-workflows - -name: Test 2 - -on: - push: - branches: - - 'main' - pull_request: - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -env: - # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' - # For PRs you can change the inner fallback ('main') - # For pushes you change the outer fallback ('main') - # The logic below is used during releases and depends on having an equivalent branch name in the core repo. - CORE_REPO_SHA: ${{ github.event_name == 'pull_request' && ( - contains(github.event.pull_request.labels.*.name, 'prepare-release') && github.event.pull_request.head.ref || - contains(github.event.pull_request.labels.*.name, 'backport') && github.event.pull_request.base.ref || - 'main' - ) || 'main' }} - CONTRIB_REPO_SHA: main - PIP_EXISTS_ACTION: w - -jobs: - - py313-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-asyncpg-wrapt1 -- -ra - - py313-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-asyncpg-wrapt2 -- -ra - - py314-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-asyncpg-wrapt1 -- -ra - - py314-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-asyncpg-wrapt2 -- -ra - - py39-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlite3 -- -ra - - py310-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-sqlite3 -- -ra - - py311-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-sqlite3 -- -ra - - py312-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-sqlite3 -- -ra - - py313-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-sqlite3 -- -ra - - py314-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-sqlite3 -- -ra - - pypy3-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra - - py39-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra - - py310-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-wsgi -- -ra - - py311-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-wsgi -- -ra - - py312-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-wsgi -- -ra - - py313-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-wsgi -- -ra - - py314-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-wsgi -- -ra - - pypy3-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-wsgi -- -ra - - py39-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt1 -- -ra - - py39-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: - name: instrumentation-grpc-0-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt2 -- -ra - - py39-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt1 -- -ra - - py39-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt2 -- -ra - - py310-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra - - py310-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: - name: instrumentation-grpc-0-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra - - py310-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra - - py310-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra - - py311-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-grpc-0-wrapt1 -- -ra - - py311-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: - name: instrumentation-grpc-0-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-grpc-0-wrapt2 -- -ra - - py311-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-grpc-1-wrapt1 -- -ra - - py311-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-grpc-1-wrapt2 -- -ra - - py312-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-grpc-0-wrapt1 -- -ra - - py312-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: - name: instrumentation-grpc-0-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-grpc-0-wrapt2 -- -ra - - py312-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-grpc-1-wrapt1 -- -ra - - py312-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-grpc-1-wrapt2 -- -ra - - py313-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-grpc-1-wrapt1 -- -ra - - py313-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-grpc-1-wrapt2 -- -ra - - py314-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-grpc-1-wrapt1 -- -ra - - py314-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-grpc-1-wrapt2 -- -ra - - py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra - - py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra - - py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra - - py310-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra - - py311-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-sqlalchemy-1 -- -ra - - py311-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-sqlalchemy-2 -- -ra - - py312-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-sqlalchemy-1 -- -ra - - py312-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-sqlalchemy-2 -- -ra - - py313-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-sqlalchemy-1 -- -ra - - py313-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-sqlalchemy-2 -- -ra - - py314-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-sqlalchemy-2 -- -ra - - pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: - name: instrumentation-sqlalchemy-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra - - pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra - - pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra - - py39-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-redis -- -ra - - py310-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-redis -- -ra - - py311-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-redis -- -ra - - py312-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-redis -- -ra - - py313-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-redis -- -ra - - py314-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-redis -- -ra - - pypy3-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-redis -- -ra - - py39-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-remoulade -- -ra - - py310-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-remoulade -- -ra - - py311-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-remoulade -- -ra - - py312-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-remoulade -- -ra - - py313-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-remoulade -- -ra - - py314-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-remoulade -- -ra - - py39-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-celery -- -ra - - py310-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-celery -- -ra - - py311-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-celery -- -ra - - py312-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-celery -- -ra - - py313-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-celery -- -ra - - py314-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-celery -- -ra - - pypy3-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-celery -- -ra - - py39-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-system-metrics -- -ra - - py310-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-system-metrics -- -ra - - py311-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-system-metrics -- -ra - - py312-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-system-metrics -- -ra - - py313-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-system-metrics -- -ra - - py314-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-system-metrics -- -ra - - pypy3-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-system-metrics -- -ra - - py39-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-threading -- -ra - - py310-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-threading -- -ra - - py311-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-threading -- -ra - - py312-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-threading -- -ra - - py313-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-threading -- -ra - - py314-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-threading -- -ra - - pypy3-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-threading -- -ra - - py39-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-tornado -- -ra - - py310-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-tornado -- -ra - - py311-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-tornado -- -ra - - py312-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-tornado -- -ra - - py313-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-tornado -- -ra - - py314-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-tornado -- -ra - - pypy3-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-tornado -- -ra - - py39-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-tortoiseorm -- -ra - - py310-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-tortoiseorm -- -ra - - py311-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-tortoiseorm -- -ra - - py312-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-tortoiseorm -- -ra - - py313-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-tortoiseorm -- -ra - - py314-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-tortoiseorm -- -ra - - pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra - - py39-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: - name: instrumentation-httpx-0-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt1 -- -ra - - py39-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt2 -- -ra - - py39-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: - name: instrumentation-httpx-1-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt1 -- -ra - - py39-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt2 -- -ra - - py310-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: - name: instrumentation-httpx-0-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-httpx-0-wrapt1 -- -ra - - py310-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-httpx-0-wrapt2 -- -ra - - py310-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: - name: instrumentation-httpx-1-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-httpx-1-wrapt1 -- -ra - - py310-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-httpx-1-wrapt2 -- -ra - - py311-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: - name: instrumentation-httpx-0-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-httpx-0-wrapt1 -- -ra - - py311-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-httpx-0-wrapt2 -- -ra - - py311-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: - name: instrumentation-httpx-1-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-httpx-1-wrapt1 -- -ra - - py311-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-httpx-1-wrapt2 -- -ra - - py312-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: - name: instrumentation-httpx-0-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-httpx-0-wrapt1 -- -ra - - py312-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-httpx-0-wrapt2 -- -ra - - py312-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: - name: instrumentation-httpx-1-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-httpx-1-wrapt1 -- -ra - - py312-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-httpx-1-wrapt2 -- -ra - - py313-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: - name: instrumentation-httpx-1-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-httpx-1-wrapt1 -- -ra - - py313-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-httpx-1-wrapt2 -- -ra - - py314-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: - name: instrumentation-httpx-1-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-httpx-1-wrapt1 -- -ra - - py314-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-httpx-1-wrapt2 -- -ra - - pypy3-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-httpx-0-wrapt2 -- -ra - - pypy3-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-httpx-1-wrapt2 -- -ra - - py39-test-util-http_ubuntu-latest: - name: util-http 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-util-http -- -ra - - py310-test-util-http_ubuntu-latest: - name: util-http 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-util-http -- -ra - - py311-test-util-http_ubuntu-latest: - name: util-http 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-util-http -- -ra - - py312-test-util-http_ubuntu-latest: - name: util-http 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-util-http -- -ra - - py313-test-util-http_ubuntu-latest: - name: util-http 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-util-http -- -ra - - py314-test-util-http_ubuntu-latest: - name: util-http 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-util-http -- -ra - - pypy3-test-util-http_ubuntu-latest: - name: util-http pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-util-http -- -ra - - py39-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-credential-provider-gcp -- -ra - - py310-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-exporter-credential-provider-gcp -- -ra - - py311-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-exporter-credential-provider-gcp -- -ra - - py312-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-exporter-credential-provider-gcp -- -ra - - py313-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-exporter-credential-provider-gcp -- -ra - - py314-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-exporter-credential-provider-gcp -- -ra - - py39-test-util-genai_ubuntu-latest: - name: util-genai 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-util-genai -- -ra - - py310-test-util-genai_ubuntu-latest: - name: util-genai 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-util-genai -- -ra - - py311-test-util-genai_ubuntu-latest: - name: util-genai 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-util-genai -- -ra - - py312-test-util-genai_ubuntu-latest: - name: util-genai 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-util-genai -- -ra - - py313-test-util-genai_ubuntu-latest: - name: util-genai 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-util-genai -- -ra - - py314-test-util-genai_ubuntu-latest: - name: util-genai 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-util-genai -- -ra - - pypy3-test-util-genai_ubuntu-latest: - name: util-genai pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-util-genai -- -ra - - py39-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-aws-xray-0 -- -ra - - py39-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-aws-xray-1 -- -ra - - py310-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-propagator-aws-xray-0 -- -ra - - py310-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-propagator-aws-xray-1 -- -ra - - py311-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-propagator-aws-xray-0 -- -ra - - py311-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-propagator-aws-xray-1 -- -ra - - py312-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-propagator-aws-xray-0 -- -ra - - py312-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-propagator-aws-xray-1 -- -ra - - py313-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-propagator-aws-xray-0 -- -ra - - py313-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-propagator-aws-xray-1 -- -ra - - py314-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-propagator-aws-xray-0 -- -ra - - py314-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-propagator-aws-xray-1 -- -ra - - pypy3-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra - - pypy3-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra - - py39-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-ot-trace -- -ra - - py310-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-propagator-ot-trace -- -ra - - py311-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-propagator-ot-trace -- -ra - - py312-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-propagator-ot-trace -- -ra - - py313-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-propagator-ot-trace -- -ra - - py314-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-propagator-ot-trace -- -ra - - pypy3-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-propagator-ot-trace -- -ra - - py39-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt1 -- -ra - - py39-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt2 -- -ra - - py39-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt1 -- -ra - - py39-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt2 -- -ra - - py310-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-sio-pika-0-wrapt1 -- -ra - - py310-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-sio-pika-0-wrapt2 -- -ra - - py310-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-sio-pika-1-wrapt1 -- -ra - - py310-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-sio-pika-1-wrapt2 -- -ra - - py311-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-sio-pika-0-wrapt1 -- -ra - - py311-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-sio-pika-0-wrapt2 -- -ra - - py311-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-sio-pika-1-wrapt1 -- -ra - - py311-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-sio-pika-1-wrapt2 -- -ra - - py312-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-sio-pika-0-wrapt1 -- -ra - - py312-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-sio-pika-0-wrapt2 -- -ra - - py312-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-sio-pika-1-wrapt1 -- -ra - - py312-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-sio-pika-1-wrapt2 -- -ra - - py313-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-sio-pika-0-wrapt1 -- -ra - - py313-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-sio-pika-0-wrapt2 -- -ra - - py313-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-sio-pika-1-wrapt1 -- -ra - - py313-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-sio-pika-1-wrapt2 -- -ra - - py314-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-sio-pika-0-wrapt1 -- -ra - - py314-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-sio-pika-0-wrapt2 -- -ra - - py314-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-sio-pika-1-wrapt1 -- -ra - - py314-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-sio-pika-1-wrapt2 -- -ra - - pypy3-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sio-pika-0-wrapt2 -- -ra - - pypy3-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sio-pika-1-wrapt2 -- -ra - - py39-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra - - py39-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra - - py39-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra - - py39-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra - - py310-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra - - py310-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra - - py310-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra - - py310-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra - - py311-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-0 -- -ra - - py311-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-1 -- -ra - - py311-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-2 -- -ra - - py311-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aio-pika-3 -- -ra - - py312-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-0 -- -ra - - py312-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-1 -- -ra - - py312-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-2 -- -ra - - py312-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aio-pika-3 -- -ra - - py313-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aio-pika-0 -- -ra - - py313-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aio-pika-1 -- -ra - - py313-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aio-pika-2 -- -ra - - py313-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aio-pika-3 -- -ra - - py314-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aio-pika-0 -- -ra - - py314-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aio-pika-1 -- -ra - - py314-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aio-pika-2 -- -ra - - py314-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aio-pika-3 -- -ra - - pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra - - pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra - - pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra - - pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra - - py39-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiokafka -- -ra - - py310-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-aiokafka -- -ra - - py311-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-aiokafka -- -ra - - py312-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-aiokafka -- -ra - - py313-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-aiokafka -- -ra - - py314-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-aiokafka -- -ra - - pypy3-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-aiokafka -- -ra - - py39-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-kafka-python -- -ra - - py310-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-kafka-python -- -ra - - py311-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-kafka-python -- -ra - - py39-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra - - py310-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra - - py311-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-kafka-pythonng -- -ra - - py312-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-kafka-pythonng -- -ra - - py313-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-kafka-pythonng -- -ra - - py314-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-kafka-pythonng -- -ra - - pypy3-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-kafka-python -- -ra - - pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra - - py39-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-confluent-kafka -- -ra - - py310-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-confluent-kafka -- -ra - - py311-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-confluent-kafka -- -ra - - py312-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-confluent-kafka -- -ra - - py313-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-confluent-kafka -- -ra - - py314-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-confluent-kafka -- -ra - - py39-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncio -- -ra - - py310-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-asyncio -- -ra - - py311-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-asyncio -- -ra - - py312-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-asyncio -- -ra - - py313-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-asyncio -- -ra - - py314-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-asyncio -- -ra - - py39-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-driver -- -ra - - py39-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-scylla -- -ra - - py310-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-cassandra-driver -- -ra diff --git a/.github/workflows/test_3.yml b/.github/workflows/test_3.yml deleted file mode 100644 index d52c3a98a12..00000000000 --- a/.github/workflows/test_3.yml +++ /dev/null @@ -1,583 +0,0 @@ -# Do not edit this file. -# This file is generated automatically by executing tox -e generate-workflows - -name: Test 3 - -on: - push: - branches: - - 'main' - pull_request: - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -env: - # Set the SHA to the branch name if the PR has a label 'prepare-release' or 'backport' otherwise, set it to 'main' - # For PRs you can change the inner fallback ('main') - # For pushes you change the outer fallback ('main') - # The logic below is used during releases and depends on having an equivalent branch name in the core repo. - CORE_REPO_SHA: ${{ github.event_name == 'pull_request' && ( - contains(github.event.pull_request.labels.*.name, 'prepare-release') && github.event.pull_request.head.ref || - contains(github.event.pull_request.labels.*.name, 'backport') && github.event.pull_request.base.ref || - 'main' - ) || 'main' }} - CONTRIB_REPO_SHA: main - PIP_EXISTS_ACTION: w - -jobs: - - py310-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-cassandra-scylla -- -ra - - py311-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-cassandra-driver -- -ra - - py311-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-cassandra-scylla -- -ra - - py312-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-cassandra-driver -- -ra - - py312-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-instrumentation-cassandra-scylla -- -ra - - py313-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-cassandra-driver -- -ra - - py313-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-instrumentation-cassandra-scylla -- -ra - - py314-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-cassandra-driver -- -ra - - py314-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra - - pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra - - py39-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra - - py310-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-processor-baggage -- -ra - - py311-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-processor-baggage -- -ra - - py312-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-processor-baggage -- -ra - - py313-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-processor-baggage -- -ra - - py314-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-processor-baggage -- -ra - - pypy3-test-processor-baggage_ubuntu-latest: - name: processor-baggage pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-processor-baggage -- -ra - - py39-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opamp-client-latest -- -ra - - py39-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opamp-client-lowest -- -ra - - py310-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-opamp-client-latest -- -ra - - py310-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-opamp-client-lowest -- -ra - - py311-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-opamp-client-latest -- -ra - - py311-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-opamp-client-lowest -- -ra - - py312-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-opamp-client-latest -- -ra - - py312-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-opamp-client-lowest -- -ra - - py313-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-opamp-client-latest -- -ra - - py313-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py313-test-opamp-client-lowest -- -ra - - py314-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-opamp-client-latest -- -ra - - py314-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.14 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py314-test-opamp-client-lowest -- -ra diff --git a/README.md b/README.md index 10aae26d9a1..6b7de51bfa7 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,8 @@ license
- - Build Status 0 - - - Build Status 1 + + Build Status Beta

From 7384e45262f67b3cff4fa9369f90657323e21893 Mon Sep 17 00:00:00 2001 From: Aaron Abbott Date: Fri, 3 Apr 2026 21:01:06 +0200 Subject: [PATCH 50/78] Add MikeGoldsmith to approvers (#4392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6b7de51bfa7..355493db1e5 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ For more information about the maintainer role, see the [community repository](h - [Keith Decker](https://github.com/keith-decker), Cisco/Splunk - [Liudmila Molkova](https://github.com/lmolkova), Grafana Labs - [Lukas Hering](https://github.com/herin049), Oracle +- [Mike Goldsmith](https://github.com/MikeGoldsmith), Honeycomb - [Owais Lone](https://github.com/owais), Splunk - [Pablo Collins](https://github.com/pmcollins), Splunk - [Sanket Mehta](https://github.com/sanketmehta28), Cisco From af11fc737a155984b79afb11ec4a392afc47f1f7 Mon Sep 17 00:00:00 2001 From: Surya Date: Tue, 7 Apr 2026 08:57:47 -0400 Subject: [PATCH 51/78] feat(genai-anthropic): wrappers for async messages methods (#4346) * wip: wrappers for async message wrappers. * wip: replacing the invocation response attributes with new attributes function. * wip: cleaning up the function. * polish: cleaning up the response attribution using event accumulation method. * wip: rearranging the code in anthropic wrappers. * polish: added a changelog. * wip: fixing lint, typecheck and precommit failures. * wip: keeping anthropic wrapper same as openai wrapper. * wip: removing redundant truthy checks for required attributes. --- .../CHANGELOG.md | 5 +- .../anthropic/messages_extractors.py | 32 ++ .../instrumentation/anthropic/patch.py | 15 +- .../instrumentation/anthropic/wrappers.py | 506 +++++++++++------ .../tests/test_async_wrappers.py | 536 ++++++++++++++++++ .../tests/test_sync_messages.py | 2 +- 6 files changed, 911 insertions(+), 185 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-anthropic/CHANGELOG.md index 5cf210fbd14..dfa9e01631d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Add async Anthropic message stream wrappers and manager wrappers, with wrapper + tests ([#4346](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4346)) + - `AsyncMessagesStreamWrapper` for async message stream telemetry + - `AsyncMessagesStreamManagerWrapper` for async `Messages.stream()` telemetry - Add sync streaming support for `Messages.create(stream=True)` and `Messages.stream()` ([#4155](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4155)) - `StreamWrapper` for handling `Messages.create(stream=True)` telemetry @@ -22,4 +26,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Captures response attributes: `gen_ai.response.id`, `gen_ai.response.model`, `gen_ai.response.finish_reasons`, `gen_ai.usage.input_tokens`, `gen_ai.usage.output_tokens` - Error handling with `error.type` attribute - Minimum supported anthropic version is 0.16.0 (SDK uses modern `anthropic.resources.messages` module structure introduced in this version) - diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/messages_extractors.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/messages_extractors.py index 907aa08d39d..8c3dcf26ecd 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/messages_extractors.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/messages_extractors.py @@ -29,6 +29,7 @@ ) from opentelemetry.util.genai.types import ( InputMessage, + LLMInvocation, MessagePart, OutputMessage, ) @@ -153,6 +154,37 @@ def get_output_messages_from_message( ] +def set_invocation_response_attributes( + invocation: LLMInvocation, + message: Message | None, + capture_content: bool, +) -> None: + if message is None: + return + + invocation.response_model_name = message.model + invocation.response_id = message.id + + finish_reason = normalize_finish_reason(message.stop_reason) + if finish_reason: + invocation.finish_reasons = [finish_reason] + + tokens = extract_usage_tokens(message.usage) + invocation.input_tokens = tokens.input_tokens + invocation.output_tokens = tokens.output_tokens + if tokens.cache_creation_input_tokens is not None: + invocation.attributes[GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS] = ( + tokens.cache_creation_input_tokens + ) + if tokens.cache_read_input_tokens is not None: + invocation.attributes[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] = ( + tokens.cache_read_input_tokens + ) + + if capture_content: + invocation.output_messages = get_output_messages_from_message(message) + + def extract_params( # pylint: disable=too-many-locals *, max_tokens: int | None = None, diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py index 2392dfcd08f..4dc8b55d388 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py @@ -14,6 +14,8 @@ """Patching functions for Anthropic instrumentation.""" +from __future__ import annotations + import logging from typing import TYPE_CHECKING, Any, Callable, Union, cast @@ -56,7 +58,7 @@ def messages_create( Union[ "AnthropicMessage", "AnthropicStream[RawMessageStreamEvent]", - MessagesStreamWrapper, + MessagesStreamWrapper[None], ], ]: """Wrap the `create` method of the `Messages` class to trace it.""" @@ -76,7 +78,7 @@ def traced_method( ) -> Union[ "AnthropicMessage", "AnthropicStream[RawMessageStreamEvent]", - MessagesStreamWrapper, + MessagesStreamWrapper[None], ]: params = extract_params(*args, **kwargs) attributes = get_llm_request_attributes(params, instance) @@ -121,13 +123,6 @@ def traced_method( raise return cast( - Callable[ - ..., - Union[ - "AnthropicMessage", - "AnthropicStream[RawMessageStreamEvent]", - MessagesStreamWrapper, - ], - ], + 'Callable[..., Union["AnthropicMessage", "AnthropicStream[RawMessageStreamEvent]", MessagesStreamWrapper[None]]]', traced_method, ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py index 585d70a9f97..52e2e68582b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py @@ -15,42 +15,94 @@ from __future__ import annotations import logging +from contextlib import AsyncExitStack, ExitStack, contextmanager from types import TracebackType -from typing import TYPE_CHECKING, Callable, Iterator, Optional +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Generator, + Generic, + Iterator, + TypeVar, + cast, +) from opentelemetry.util.genai.handler import TelemetryHandler from opentelemetry.util.genai.types import ( Error, LLMInvocation, - MessagePart, - OutputMessage, ) -from .messages_extractors import ( - GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, - GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, - extract_usage_tokens, - get_output_messages_from_message, -) -from .utils import ( - StreamBlockState, - create_stream_block_state, - normalize_finish_reason, - stream_block_state_to_part, - update_stream_block_state, -) +from .messages_extractors import set_invocation_response_attributes + +try: + from anthropic.lib.streaming._messages import ( # pylint: disable=no-name-in-module + accumulate_event as _sdk_accumulate_event, + ) +except ImportError: + _sdk_accumulate_event = None if TYPE_CHECKING: - from anthropic._streaming import Stream + from anthropic._streaming import AsyncStream, Stream + from anthropic.lib.streaming._messages import ( # pylint: disable=no-name-in-module + AsyncMessageStream, + AsyncMessageStreamManager, + MessageStream, + MessageStreamManager, + ) + from anthropic.lib.streaming._types import ( # pylint: disable=no-name-in-module + ParsedMessageStreamEvent, + ) from anthropic.types import ( Message, - MessageDeltaUsage, RawMessageStreamEvent, - Usage, ) + from anthropic.types.parsed_message import ParsedMessage _logger = logging.getLogger(__name__) +ResponseT = TypeVar("ResponseT") +ResponseFormatT = TypeVar("ResponseFormatT") +accumulate_event = cast("Callable[..., Message] | None", _sdk_accumulate_event) + + +def _set_response_attributes( + invocation: LLMInvocation, + result: "Message | None", + capture_content: bool, +) -> None: + set_invocation_response_attributes(invocation, result, capture_content) + + +class _ResponseProxy(Generic[ResponseT]): + def __init__(self, response: ResponseT, finalize: Callable[[], None]): + self._response: Any = response + self._finalize = finalize + + def close(self) -> None: + try: + self._response.close() + finally: + self._finalize() + + def __getattr__(self, name: str): + return getattr(self._response, name) + + +class _AsyncResponseProxy(Generic[ResponseT]): + def __init__(self, response: ResponseT, finalize: Callable[[], None]): + self._response: Any = response + self._finalize = finalize + + async def aclose(self) -> None: + try: + await self._response.aclose() + finally: + self._finalize() + + def __getattr__(self, name: str): + return getattr(self._response, name) class MessageWrapper: @@ -62,33 +114,9 @@ def __init__(self, message: Message, capture_content: bool): def extract_into(self, invocation: LLMInvocation) -> None: """Extract response data into the invocation.""" - if self._message.model: - invocation.response_model_name = self._message.model - - if self._message.id: - invocation.response_id = self._message.id - - finish_reason = normalize_finish_reason(self._message.stop_reason) - if finish_reason: - invocation.finish_reasons = [finish_reason] - - if self._message.usage: - tokens = extract_usage_tokens(self._message.usage) - invocation.input_tokens = tokens.input_tokens - invocation.output_tokens = tokens.output_tokens - if tokens.cache_creation_input_tokens is not None: - invocation.attributes[ - GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS - ] = tokens.cache_creation_input_tokens - if tokens.cache_read_input_tokens is not None: - invocation.attributes[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] = ( - tokens.cache_read_input_tokens - ) - - if self._capture_content: - invocation.output_messages = get_output_messages_from_message( - self._message - ) + set_invocation_response_attributes( + invocation, self._message, self._capture_content + ) @property def message(self) -> Message: @@ -96,73 +124,104 @@ def message(self) -> Message: return self._message -class MessagesStreamWrapper(Iterator["RawMessageStreamEvent"]): +class MessagesStreamWrapper( + Generic[ResponseFormatT], + Iterator[ + "RawMessageStreamEvent | ParsedMessageStreamEvent[ResponseFormatT]" + ], +): """Wrapper for Anthropic Stream that handles telemetry.""" def __init__( self, - stream: Stream[RawMessageStreamEvent], + stream: "Stream[RawMessageStreamEvent] | MessageStream[ResponseFormatT]", handler: TelemetryHandler, invocation: LLMInvocation, capture_content: bool, ): - self._stream = stream - self._handler = handler - self._invocation = invocation - self._response_id: Optional[str] = None - self._response_model: Optional[str] = None - self._stop_reason: Optional[str] = None - self._input_tokens: Optional[int] = None - self._output_tokens: Optional[int] = None - self._cache_creation_input_tokens: Optional[int] = None - self._cache_read_input_tokens: Optional[int] = None + self.stream = stream + self.handler = handler + self.invocation = invocation + self._message: "Message | ParsedMessage[ResponseFormatT] | None" = None self._capture_content = capture_content - self._content_blocks: dict[int, StreamBlockState] = {} self._finalized = False - def _update_usage(self, usage: Usage | MessageDeltaUsage | None) -> None: - tokens = extract_usage_tokens(usage) - if tokens.input_tokens is not None: - self._input_tokens = tokens.input_tokens - if tokens.output_tokens is not None: - self._output_tokens = tokens.output_tokens - if tokens.cache_creation_input_tokens is not None: - self._cache_creation_input_tokens = ( - tokens.cache_creation_input_tokens - ) - if tokens.cache_read_input_tokens is not None: - self._cache_read_input_tokens = tokens.cache_read_input_tokens - - def _process_chunk(self, chunk: RawMessageStreamEvent) -> None: - """Extract telemetry data from a streaming chunk.""" - if chunk.type == "message_start": - message = chunk.message - if message.id: - self._response_id = message.id - if message.model: - self._response_model = message.model - self._update_usage(message.usage) - elif chunk.type == "message_delta": - if chunk.delta.stop_reason: - self._stop_reason = normalize_finish_reason( - chunk.delta.stop_reason + def __enter__(self) -> "MessagesStreamWrapper[ResponseFormatT]": + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + try: + if exc_type is not None: + self._fail( + str(exc_val), type(exc_val) if exc_val else Exception ) - self._update_usage(chunk.usage) - elif self._capture_content and chunk.type == "content_block_start": - self._content_blocks[chunk.index] = create_stream_block_state( - chunk.content_block + finally: + self.close() + return False + + def close(self) -> None: + try: + self.stream.close() + finally: + self._stop() + + def __iter__(self) -> "MessagesStreamWrapper[ResponseFormatT]": + return self + + def __next__( + self, + ) -> "RawMessageStreamEvent | ParsedMessageStreamEvent[ResponseFormatT]": + try: + chunk = next(self.stream) + except StopIteration: + self._stop() + raise + except Exception as exc: + self._fail(str(exc), type(exc)) + raise + with self._safe_instrumentation("stream chunk processing"): + self._process_chunk(chunk) + return chunk + + def __getattr__(self, name: str) -> object: + return getattr(self.stream, name) + + @property + def response(self): + return _ResponseProxy(self.stream.response, self._stop) + + def _stop(self) -> None: + if self._finalized: + return + with self._safe_instrumentation("response attribute extraction"): + _set_response_attributes( + self.invocation, self._message, self._capture_content ) - elif self._capture_content and chunk.type == "content_block_delta": - block = self._content_blocks.get(chunk.index) - if block is not None: - update_stream_block_state(block, chunk.delta) + with self._safe_instrumentation("stop_llm"): + self.handler.stop_llm(self.invocation) + self._finalized = True + + def _fail(self, message: str, error_type: type[BaseException]) -> None: + if self._finalized: + return + with self._safe_instrumentation("fail_llm"): + self.handler.fail_llm( + self.invocation, Error(message=message, type=error_type) + ) + self._finalized = True @staticmethod + @contextmanager def _safe_instrumentation( - callback: Callable[[], object], context: str - ) -> None: + context: str, + ) -> Generator[None, None, None]: try: - callback() + yield except Exception: # pylint: disable=broad-exception-caught _logger.debug( "Anthropic MessagesStreamWrapper instrumentation error in %s", @@ -170,90 +229,51 @@ def _safe_instrumentation( exc_info=True, ) - def _set_invocation_response_attributes(self) -> None: - """Extract accumulated stream state into the invocation.""" - if self._response_model: - self._invocation.response_model_name = self._response_model - if self._response_id: - self._invocation.response_id = self._response_id - if self._stop_reason: - self._invocation.finish_reasons = [self._stop_reason] - if self._input_tokens is not None: - self._invocation.input_tokens = self._input_tokens - if self._output_tokens is not None: - self._invocation.output_tokens = self._output_tokens - if self._cache_creation_input_tokens is not None: - self._invocation.attributes[ - GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS - ] = self._cache_creation_input_tokens - if self._cache_read_input_tokens is not None: - self._invocation.attributes[ - GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS - ] = self._cache_read_input_tokens - - if self._capture_content and self._content_blocks: - parts: list[MessagePart] = [] - for index in sorted(self._content_blocks): - part = stream_block_state_to_part(self._content_blocks[index]) - if part is not None: - parts.append(part) - self._invocation.output_messages = [ - OutputMessage( - role="assistant", - parts=parts, - finish_reason=self._stop_reason or "", - ) - ] - - def _stop(self) -> None: - if self._finalized: - return - self._safe_instrumentation( - self._set_invocation_response_attributes, - "response attribute extraction", - ) - self._safe_instrumentation( - lambda: self._handler.stop_llm(self._invocation), - "stop_llm", + def _process_chunk( + self, + chunk: "RawMessageStreamEvent | ParsedMessageStreamEvent[ResponseFormatT]", + ) -> None: + """Accumulate a final message snapshot from a streaming chunk.""" + snapshot = cast( + "ParsedMessage[ResponseFormatT] | None", + getattr(self.stream, "current_message_snapshot", None), ) - self._finalized = True - - def _fail(self, message: str, error_type: type[BaseException]) -> None: - if self._finalized: + if snapshot is not None: + self._message = snapshot + return + if accumulate_event is None: return - self._safe_instrumentation( - lambda: self._handler.fail_llm( - self._invocation, Error(message=message, type=error_type) + self._message = accumulate_event( + event=cast("RawMessageStreamEvent", chunk), + current_snapshot=cast( + "ParsedMessage[ResponseFormatT] | None", self._message ), - "fail_llm", ) - self._finalized = True - def __iter__(self) -> MessagesStreamWrapper: - return self - def __getattr__(self, name: str) -> object: - return getattr(self._stream, name) +class AsyncMessagesStreamWrapper(MessagesStreamWrapper[ResponseFormatT]): + """Wrapper for async Anthropic Stream that handles telemetry.""" - def __next__(self) -> RawMessageStreamEvent: - try: - chunk = next(self._stream) - except StopIteration: - self._stop() - raise - except Exception as exc: - self._fail(str(exc), type(exc)) - raise - self._safe_instrumentation( - lambda: self._process_chunk(chunk), - "stream chunk processing", - ) - return chunk + def __init__( + self, + stream: "AsyncStream[RawMessageStreamEvent] | AsyncMessageStream[ResponseFormatT]", + handler: TelemetryHandler, + invocation: LLMInvocation, + capture_content: bool, + ): + self.stream = stream + self.handler = handler + self.invocation = invocation + self._message: "Message | ParsedMessage[ResponseFormatT] | None" = None + self._capture_content = capture_content + self._finalized = False - def __enter__(self) -> MessagesStreamWrapper: + async def __aenter__( + self, + ) -> "AsyncMessagesStreamWrapper[ResponseFormatT]": return self - def __exit__( + async def __aexit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, @@ -265,11 +285,151 @@ def __exit__( str(exc_val), type(exc_val) if exc_val else Exception ) finally: - self.close() + await self.close() return False - def close(self) -> None: + async def close(self) -> None: # type: ignore[override] try: - self._stream.close() + await self.stream.close() finally: self._stop() + + def __aiter__(self) -> "AsyncMessagesStreamWrapper[ResponseFormatT]": + return self + + @property + def response(self) -> Any: + return _AsyncResponseProxy(self.stream.response, self._stop) + + async def __anext__( + self, + ) -> "RawMessageStreamEvent | ParsedMessageStreamEvent[ResponseFormatT]": + try: + chunk = await self.stream.__anext__() + except StopAsyncIteration: + self._stop() + raise + except Exception as exc: + self._fail(str(exc), type(exc)) + raise + with self._safe_instrumentation("stream chunk processing"): + self._process_chunk(chunk) + return chunk + + +class MessagesStreamManagerWrapper(Generic[ResponseFormatT]): + """Wrapper for sync Anthropic stream managers.""" + + def __init__( + self, + manager: "MessageStreamManager[ResponseFormatT]", + handler: TelemetryHandler, + invocation: LLMInvocation, + capture_content: bool, + ): + self._manager = manager + self._handler = handler + self._invocation = invocation + self._capture_content = capture_content + self._stream_wrapper: MessagesStreamWrapper[ResponseFormatT] | None = ( + None + ) + + def __enter__(self) -> MessagesStreamWrapper[ResponseFormatT]: + stream = self._manager.__enter__() + self._stream_wrapper = MessagesStreamWrapper( + stream, + self._handler, + self._invocation, + self._capture_content, + ) + return self._stream_wrapper + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool | None: + suppressed = False + stream_wrapper = self._stream_wrapper + self._stream_wrapper = None + with ExitStack() as cleanup: + if stream_wrapper is not None: + + def finalize_stream_wrapper() -> None: + if suppressed: + stream_wrapper.__exit__(None, None, None) + else: + stream_wrapper.__exit__(exc_type, exc_val, exc_tb) + + cleanup.callback(finalize_stream_wrapper) + suppressed = self._manager.__exit__(exc_type, exc_val, exc_tb) + return suppressed + + def __getattr__(self, name: str) -> object: + return getattr(self._manager, name) + + +class AsyncMessagesStreamManagerWrapper(Generic[ResponseFormatT]): + """Wrapper for AsyncMessageStreamManager that handles telemetry. + + Wraps AsyncMessageStreamManager from the Anthropic SDK: + https://github.com/anthropics/anthropic-sdk-python/blob/05220bc1c1079fe01f5c4babc007ec7a990859d9/src/anthropic/lib/streaming/_messages.py#L294 + """ + + def __init__( + self, + manager: "AsyncMessageStreamManager[ResponseFormatT]", + handler: TelemetryHandler, + invocation: LLMInvocation, + capture_content: bool, + ): + self._manager = manager + self._handler = handler + self._invocation = invocation + self._capture_content = capture_content + self._stream_wrapper: ( + AsyncMessagesStreamWrapper[ResponseFormatT] | None + ) = None + + async def __aenter__( + self, + ) -> AsyncMessagesStreamWrapper[ResponseFormatT]: + msg_stream = await self._manager.__aenter__() + self._stream_wrapper = AsyncMessagesStreamWrapper( + msg_stream, + self._handler, + self._invocation, + self._capture_content, + ) + return self._stream_wrapper + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool | None: + suppressed = False + stream_wrapper = self._stream_wrapper + self._stream_wrapper = None + async with AsyncExitStack() as cleanup: + if stream_wrapper is not None: + + async def finalize_stream_wrapper() -> None: + if suppressed: + await stream_wrapper.__aexit__(None, None, None) + else: + await stream_wrapper.__aexit__( + exc_type, exc_val, exc_tb + ) + + cleanup.push_async_callback(finalize_stream_wrapper) + suppressed = await self._manager.__aexit__( + exc_type, exc_val, exc_tb + ) + return suppressed + + def __getattr__(self, name: str) -> object: + return getattr(self._manager, name) diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py new file mode 100644 index 00000000000..b2055a525f4 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py @@ -0,0 +1,536 @@ +# 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 types import SimpleNamespace + +import pytest + +from opentelemetry.instrumentation.anthropic.wrappers import ( + AsyncMessagesStreamManagerWrapper, + AsyncMessagesStreamWrapper, + MessagesStreamManagerWrapper, + MessagesStreamWrapper, +) + + +def _noop_stop_llm(invocation): + del invocation + + +def _noop_fail_llm(invocation, error): + del invocation + del error + + +def _make_handler(): + return SimpleNamespace( + stop_llm=_noop_stop_llm, + fail_llm=_noop_fail_llm, + ) + + +def _make_invocation(): + return SimpleNamespace(attributes={}, request_model=None) + + +def _make_stream_wrapper(stream, handler=None): + return MessagesStreamWrapper( + stream=stream, + handler=handler or _make_handler(), + invocation=_make_invocation(), + capture_content=False, + ) + + +def _make_async_stream_wrapper(stream, handler=None): + return AsyncMessagesStreamWrapper( + stream=stream, + handler=handler or _make_handler(), + invocation=_make_invocation(), + capture_content=False, + ) + + +class _FakeSyncStream: + def __init__(self, *, events=None, error=None): + self._events = list(events or []) + self._error = error + self.close_calls = 0 + self.response = _FakeSyncResponse() + + def __iter__(self): + return self + + def __next__(self): + if self._events: + return self._events.pop(0) + if self._error is not None: + raise self._error + raise StopIteration + + def close(self): + self.close_calls += 1 + + +class _FakeAsyncStream: + def __init__(self, *, events=None, error=None): + self._events = list(events or []) + self._error = error + self.close_calls = 0 + self.final_message = SimpleNamespace(id="msg_final") + self.response = _FakeAsyncResponse() + + async def __anext__(self): + if self._events: + return self._events.pop(0) + if self._error is not None: + raise self._error + raise StopAsyncIteration + + async def close(self): + self.close_calls += 1 + + async def get_final_message(self): + return self.final_message + + +class _FakeSyncManager: + def __init__(self, stream, suppressed=False, exit_error=None): + self._stream = stream + self._suppressed = suppressed + self._exit_error = exit_error + self.exit_args = None + + def __enter__(self): + return self._stream + + def __exit__(self, exc_type, exc_val, exc_tb): + self.exit_args = (exc_type, exc_val, exc_tb) + if self._exit_error is not None: + raise self._exit_error + return self._suppressed + + +class _FakeAsyncManager: + def __init__(self, stream, suppressed=False, exit_error=None): + self._stream = stream + self._suppressed = suppressed + self._exit_error = exit_error + self.exit_args = None + + async def __aenter__(self): + return self._stream + + async def __aexit__(self, exc_type, exc_val, exc_tb): + self.exit_args = (exc_type, exc_val, exc_tb) + if self._exit_error is not None: + raise self._exit_error + return self._suppressed + + +class _FakeStreamWrapper: + def __init__(self): + self.exit_args = None + + def __exit__(self, exc_type, exc_val, exc_tb): + self.exit_args = (exc_type, exc_val, exc_tb) + return False + + +class _FakeAsyncStreamWrapper: + def __init__(self): + self.exit_args = None + + async def __aexit__(self, exc_type, exc_val, exc_tb): + self.exit_args = (exc_type, exc_val, exc_tb) + return False + + +class _FakeSyncResponse: + def __init__(self): + self.request_id = "req_sync" + self.close_calls = 0 + + def close(self): + self.close_calls += 1 + + +class _FakeAsyncResponse: + def __init__(self): + self.request_id = "req_async" + self.close_calls = 0 + self.aclose_calls = 0 + + def close(self): + self.close_calls += 1 + + async def aclose(self): + self.aclose_calls += 1 + + +def test_sync_stream_wrapper_exit_closes_without_exception(): + stream = _FakeSyncStream() + wrapper = _make_stream_wrapper(stream) + stopped = [] + + wrapper._stop = lambda: stopped.append(True) + + result = wrapper.__exit__(None, None, None) + + assert result is False + assert stream.close_calls == 1 + assert stopped == [True] + + +def test_sync_stream_wrapper_exit_fails_and_closes_on_exception(): + stream = _FakeSyncStream() + wrapper = _make_stream_wrapper(stream) + stopped = [] + failures = [] + + wrapper._stop = lambda: stopped.append(True) + wrapper._fail = lambda message, error_type: failures.append( + (message, error_type) + ) + + error = ValueError("boom") + result = wrapper.__exit__(ValueError, error, None) + + assert result is False + assert stream.close_calls == 1 + assert stopped == [True] + assert failures == [("boom", ValueError)] + + +def test_sync_stream_wrapper_processes_events_and_stops_on_completion(): + event = SimpleNamespace(type="message_start") + stream = _FakeSyncStream(events=[event]) + wrapper = _make_stream_wrapper(stream) + processed = [] + stopped = [] + + wrapper._process_chunk = processed.append + wrapper._stop = lambda: stopped.append(True) + + result = next(wrapper) + + assert result is event + assert processed == [event] + + with pytest.raises(StopIteration): + next(wrapper) + + assert stopped == [True] + + +def test_sync_stream_wrapper_fails_and_reraises_stream_errors(): + error = ValueError("boom") + stream = _FakeSyncStream(error=error) + wrapper = _make_stream_wrapper(stream) + failures = [] + + wrapper._fail = lambda message, error_type: failures.append( + (message, error_type) + ) + + with pytest.raises(ValueError, match="boom"): + next(wrapper) + + assert failures == [("boom", ValueError)] + + +def test_sync_stream_wrapper_getattr_passthrough(): + stream = _FakeSyncStream() + wrapper = _make_stream_wrapper(stream) + + assert wrapper.response.request_id == "req_sync" + + +def test_sync_stream_response_close_finalizes_wrapper(): + stream = _FakeSyncStream() + wrapper = _make_stream_wrapper(stream) + stopped = [] + + wrapper._stop = lambda: stopped.append(True) + + wrapper.response.close() + + assert stream.response.close_calls == 1 + assert stopped == [True] + + +def test_sync_manager_enter_constructs_stream_wrapper(): + stream = _FakeSyncStream() + wrapper = MessagesStreamManagerWrapper( + manager=_FakeSyncManager(stream=stream), + handler=_make_handler(), + invocation=_make_invocation(), + capture_content=False, + ) + + with wrapper as result: + assert isinstance(result, MessagesStreamWrapper) + assert result.stream is stream + assert wrapper._stream_wrapper is result + + +def test_sync_manager_exit_forwards_exception_to_stream_wrapper(): + wrapper = MessagesStreamManagerWrapper( + manager=_FakeSyncManager(stream=SimpleNamespace(), suppressed=False), + handler=SimpleNamespace(), + invocation=_make_invocation(), + capture_content=False, + ) + stream_wrapper = _FakeStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = ValueError("boom") + result = wrapper.__exit__(ValueError, error, None) + + assert result is False + assert wrapper._manager.exit_args == (ValueError, error, None) + assert stream_wrapper.exit_args == (ValueError, error, None) + + +def test_sync_manager_exit_uses_none_exception_when_manager_suppresses(): + wrapper = MessagesStreamManagerWrapper( + manager=_FakeSyncManager(stream=SimpleNamespace(), suppressed=True), + handler=SimpleNamespace(), + invocation=_make_invocation(), + capture_content=False, + ) + stream_wrapper = _FakeStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = RuntimeError("ignored") + result = wrapper.__exit__(RuntimeError, error, None) + + assert result is True + assert wrapper._manager.exit_args == (RuntimeError, error, None) + assert stream_wrapper.exit_args == (None, None, None) + + +def test_sync_manager_exit_still_finalizes_stream_wrapper_when_manager_raises(): + manager_error = RuntimeError("manager failure") + wrapper = MessagesStreamManagerWrapper( + manager=_FakeSyncManager( + stream=SimpleNamespace(), + suppressed=False, + exit_error=manager_error, + ), + handler=SimpleNamespace(), + invocation=_make_invocation(), + capture_content=False, + ) + stream_wrapper = _FakeStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = ValueError("outer") + with pytest.raises(RuntimeError, match="manager failure"): + wrapper.__exit__(ValueError, error, None) + + assert wrapper._manager.exit_args == (ValueError, error, None) + assert stream_wrapper.exit_args == (ValueError, error, None) + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_exit_closes_without_exception(): + stream = _FakeAsyncStream() + wrapper = _make_async_stream_wrapper(stream) + stopped = [] + + wrapper._stop = lambda: stopped.append(True) + + result = await wrapper.__aexit__(None, None, None) + + assert result is False + assert stream.close_calls == 1 + assert stopped == [True] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_exit_fails_and_closes_on_exception(): + stream = _FakeAsyncStream() + wrapper = _make_async_stream_wrapper(stream) + stopped = [] + failures = [] + + wrapper._stop = lambda: stopped.append(True) + wrapper._fail = lambda message, error_type: failures.append( + (message, error_type) + ) + + error = ValueError("boom") + result = await wrapper.__aexit__(ValueError, error, None) + + assert result is False + assert stream.close_calls == 1 + assert stopped == [True] + assert failures == [("boom", ValueError)] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_close_uses_close_and_stops(): + stream = _FakeAsyncStream() + wrapper = _make_async_stream_wrapper(stream) + stopped = [] + + wrapper._stop = lambda: stopped.append(True) + + await wrapper.close() + + assert stream.close_calls == 1 + assert stopped == [True] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_processes_events_and_stops_on_completion(): + event = SimpleNamespace(type="message_start") + stream = _FakeAsyncStream(events=[event]) + wrapper = _make_async_stream_wrapper(stream) + processed = [] + stopped = [] + + wrapper._process_chunk = processed.append + wrapper._stop = lambda: stopped.append(True) + + result = await wrapper.__anext__() + + assert result is event + assert processed == [event] + + with pytest.raises(StopAsyncIteration): + await wrapper.__anext__() + + assert stopped == [True] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_fails_and_reraises_stream_errors(): + error = ValueError("boom") + stream = _FakeAsyncStream(error=error) + wrapper = _make_async_stream_wrapper(stream) + failures = [] + + wrapper._fail = lambda message, error_type: failures.append( + (message, error_type) + ) + + with pytest.raises(ValueError, match="boom"): + await wrapper.__anext__() + + assert failures == [("boom", ValueError)] + + +@pytest.mark.asyncio +async def test_async_stream_wrapper_preserves_stream_helper_methods(): + stream = _FakeAsyncStream() + wrapper = _make_async_stream_wrapper(stream) + + result = await wrapper.get_final_message() + + assert result is stream.final_message + assert wrapper.response.request_id == "req_async" + + +@pytest.mark.asyncio +async def test_async_stream_response_aclose_finalizes_wrapper(): + stream = _FakeAsyncStream() + wrapper = _make_async_stream_wrapper(stream) + stopped = [] + + wrapper._stop = lambda: stopped.append(True) + + await wrapper.response.aclose() + + assert stream.response.aclose_calls == 1 + assert stopped == [True] + + +@pytest.mark.asyncio +async def test_async_manager_enter_constructs_async_stream_wrapper(): + stream = _FakeAsyncStream() + wrapper = AsyncMessagesStreamManagerWrapper( + manager=_FakeAsyncManager(stream=stream), + handler=_make_handler(), + invocation=_make_invocation(), + capture_content=False, + ) + + async with wrapper as result: + assert isinstance(result, AsyncMessagesStreamWrapper) + assert result.stream is stream + assert wrapper._stream_wrapper is result + + +@pytest.mark.asyncio +async def test_async_manager_exit_forwards_exception_to_stream_wrapper(): + wrapper = AsyncMessagesStreamManagerWrapper( + manager=_FakeAsyncManager(stream=SimpleNamespace(), suppressed=False), + handler=SimpleNamespace(), + invocation=_make_invocation(), + capture_content=False, + ) + stream_wrapper = _FakeAsyncStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = ValueError("boom") + result = await wrapper.__aexit__(ValueError, error, None) + + assert result is False + assert wrapper._manager.exit_args == (ValueError, error, None) + assert stream_wrapper.exit_args == (ValueError, error, None) + + +@pytest.mark.asyncio +async def test_async_manager_exit_uses_none_exception_when_manager_suppresses(): + wrapper = AsyncMessagesStreamManagerWrapper( + manager=_FakeAsyncManager(stream=SimpleNamespace(), suppressed=True), + handler=SimpleNamespace(), + invocation=_make_invocation(), + capture_content=False, + ) + stream_wrapper = _FakeAsyncStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = RuntimeError("ignored") + result = await wrapper.__aexit__(RuntimeError, error, None) + + assert result is True + assert wrapper._manager.exit_args == (RuntimeError, error, None) + assert stream_wrapper.exit_args == (None, None, None) + + +@pytest.mark.asyncio +async def test_async_manager_exit_still_finalizes_stream_wrapper_when_manager_raises(): + manager_error = RuntimeError("manager failure") + wrapper = AsyncMessagesStreamManagerWrapper( + manager=_FakeAsyncManager( + stream=SimpleNamespace(), + suppressed=False, + exit_error=manager_error, + ), + handler=SimpleNamespace(), + invocation=_make_invocation(), + capture_content=False, + ) + stream_wrapper = _FakeAsyncStreamWrapper() + wrapper._stream_wrapper = stream_wrapper + + error = ValueError("outer") + with pytest.raises(RuntimeError, match="manager failure"): + await wrapper.__aexit__(ValueError, error, None) + + assert wrapper._manager.exit_args == (ValueError, error, None) + assert stream_wrapper.exit_args == (ValueError, error, None) diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_sync_messages.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_sync_messages.py index 6bce6f2e162..a073f3b569b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_sync_messages.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_sync_messages.py @@ -826,7 +826,7 @@ def __getattr__(self, name): return getattr(self._inner, name) monkeypatch.setattr( - stream, "_stream", ErrorInjectingStreamDelegate(stream._stream) + stream, "stream", ErrorInjectingStreamDelegate(stream.stream) ) with pytest.raises( From 0f9247881f65ecb69a3ef803fafed8775f3277fb Mon Sep 17 00:00:00 2001 From: Surya Date: Tue, 7 Apr 2026 09:24:39 -0400 Subject: [PATCH 52/78] feat(genai-openai): OpenAI responses extractors (#4337) * wip: pydantic based responses api attributes extraction. * polish: fixing the linting around files. * refactor: update changelog. * polish: removing pydantic hard dependency and making pydantic version compatible with openai supported version. * wip: tox validation for pydantic 1.x version. * generated new workflows. * adding the pydantic test to new test file and removing old files. * wip: generated workflows. * wip: removed unwanted truthiness checks and simplified the test suite. * polish: fixed precommit. --------- Co-authored-by: Riccardo Magliocchetti --- .github/workflows/test.yml | 19 + .../CHANGELOG.md | 3 + .../openai_v2/response_extractors.py | 419 ++++++++++++++++++ .../tests/requirements.pydantic1.txt | 55 +++ .../tests/test_response_extractors.py | 365 +++++++++++++++ tox.ini | 3 + 6 files changed, 864 insertions(+) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_extractors.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.pydantic1.txt create mode 100644 instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_extractors.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 171d36f716b..8aba00e1c21 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -252,6 +252,25 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-openai-v2-latest -- -ra + py313-test-instrumentation-openai-v2-pydantic1_ubuntu-latest: + name: instrumentation-openai-v2-pydantic1 3.13 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py313-test-instrumentation-openai-v2-pydantic1 -- -ra + pypy3-test-instrumentation-openai-v2-oldest_ubuntu-latest: name: instrumentation-openai-v2-oldest pypy-3.9 Ubuntu runs-on: ubuntu-latest diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md index 76d2deabc45..6fc545df24c 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/CHANGELOG.md @@ -19,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4280](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4280)) - Add async wrappers for OpenAI Responses API streams and response stream managers ([#4325](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4325)) +- Add strongly typed Responses API extractors with validation and content + extraction improvements + ([#4337](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4337)) ## Version 2.3b0 (2025-12-24) diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_extractors.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_extractors.py new file mode 100644 index 00000000000..2d5e8702b19 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_extractors.py @@ -0,0 +1,419 @@ +# 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 __future__ import annotations + +import logging +from collections.abc import Mapping, Sequence +from typing import TYPE_CHECKING, List, Optional, TypeVar, Union + +from pydantic import BaseModel, Field, StrictInt, StrictStr, ValidationError + +from opentelemetry.semconv._incubating.attributes import ( + openai_attributes as OpenAIAttributes, +) + +_PYDANTIC_V2 = hasattr(BaseModel, "model_validate") + +if _PYDANTIC_V2: + from pydantic import ConfigDict +else: + ConfigDict = None + +if TYPE_CHECKING: + from opentelemetry.util.genai.types import ( + InputMessage, + LLMInvocation, + OutputMessage, + Text, + ) + +try: + from opentelemetry.util.genai.types import ( + InputMessage, + OutputMessage, + Text, + ) +except ImportError: + InputMessage = None + OutputMessage = None + Text = None + +GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS = "gen_ai.usage.cache_read.input_tokens" +GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS = ( + "gen_ai.usage.cache_creation.input_tokens" +) + +_logger = logging.getLogger(__name__) +ModelT = TypeVar("ModelT", bound=BaseModel) + + +class _ExtractorModel(BaseModel): + if _PYDANTIC_V2: + model_config = ConfigDict(extra="ignore", from_attributes=True) + else: + + class Config: + extra = "ignore" + orm_mode = True + + +class _ResponseTextFormatModel(_ExtractorModel): + type: Optional[StrictStr] = None + + +class _ResponseTextConfigModel(_ExtractorModel): + format: Optional[_ResponseTextFormatModel] = None + + +class _ResponseInputContentModel(_ExtractorModel): + text: Optional[StrictStr] = None + + +class _ResponseInputItemModel(_ExtractorModel): + role: Optional[StrictStr] = None + content: Optional[Union[StrictStr, List[_ResponseInputContentModel]]] = ( + None + ) + + +class _ResponsesRequestModel(_ExtractorModel): + instructions: Optional[StrictStr] = None + input: Optional[Union[StrictStr, List[_ResponseInputItemModel]]] = None + text: Optional[_ResponseTextConfigModel] = None + + +class _ResponseOutputContentModel(_ExtractorModel): + type: Optional[StrictStr] = None + text: Optional[StrictStr] = None + refusal: Optional[StrictStr] = None + + +class _ResponseOutputItemModel(_ExtractorModel): + type: Optional[StrictStr] = None + role: Optional[StrictStr] = None + status: Optional[StrictStr] = None + content: List[_ResponseOutputContentModel] = Field(default_factory=list) + + +class _UsageDetailsModel(_ExtractorModel): + cached_tokens: Optional[StrictInt] = None + cache_creation_input_tokens: Optional[StrictInt] = None + + +class _UsageModel(_ExtractorModel): + input_tokens: Optional[StrictInt] = None + output_tokens: Optional[StrictInt] = None + prompt_tokens: Optional[StrictInt] = None + completion_tokens: Optional[StrictInt] = None + input_tokens_details: Optional[_UsageDetailsModel] = None + prompt_tokens_details: Optional[_UsageDetailsModel] = None + + +class _ResponsesResultModel(_ExtractorModel): + # Responses can be partial or otherwise omit `output`. Treat that as "no + # terminal message items available yet" so downstream extraction helpers + # naturally return empty lists instead of raising. + output: List[_ResponseOutputItemModel] = Field(default_factory=list) + model: Optional[StrictStr] = None + id: Optional[StrictStr] = None + service_tier: Optional[StrictStr] = None + usage: Optional[_UsageModel] = None + + +def _rebuild_model(model_type: type[BaseModel]) -> None: + if _PYDANTIC_V2: + model_type.model_rebuild(_types_namespace=globals()) + else: + model_type.update_forward_refs(**globals()) + + +for _model_type in ( + _ResponseTextFormatModel, + _ResponseTextConfigModel, + _ResponseInputContentModel, + _ResponseInputItemModel, + _ResponsesRequestModel, + _ResponseOutputContentModel, + _ResponseOutputItemModel, + _UsageDetailsModel, + _UsageModel, + _ResponsesResultModel, +): + _rebuild_model(_model_type) + + +def _validate_model( + model_type: type[ModelT], value: object, context: str +) -> ModelT | None: + try: + if _PYDANTIC_V2: + return model_type.model_validate(value) + if isinstance(value, Mapping): + return model_type.parse_obj(value) + return model_type.from_orm(value) + except ValidationError: + _logger.debug( + "OpenAI responses extractor validation failed for %s", + context, + exc_info=True, + ) + return None + + +def _validate_request_kwargs( + kwargs: Mapping[str, object], +) -> _ResponsesRequestModel | None: + return _validate_model( + _ResponsesRequestModel, kwargs, "request parameters" + ) + + +def _validate_response_result(result: object) -> _ResponsesResultModel | None: + return _validate_model(_ResponsesResultModel, result, "response payload") + + +def _coerce_response_result( + result: object | _ResponsesResultModel | None, +) -> _ResponsesResultModel | None: + if result is None: + return None + + if isinstance(result, _ResponsesResultModel): + return result + + return _validate_response_result(result) + + +def _extract_system_instruction(kwargs: Mapping[str, object]) -> list["Text"]: + """Extract system instruction from the ``instructions`` parameter.""" + if Text is None: + return [] + + request = _validate_request_kwargs(kwargs) + if request is None or request.instructions is None: + return [] + + return [Text(content=request.instructions)] + + +def _extract_input_messages( + kwargs: Mapping[str, object], +) -> list["InputMessage"]: + """Extract input messages from Responses API kwargs.""" + if InputMessage is None or Text is None: + return [] + + request = _validate_request_kwargs(kwargs) + if request is None or request.input is None: + return [] + + if isinstance(request.input, str): + return [InputMessage(role="user", parts=[Text(content=request.input)])] + + messages: list[InputMessage] = [] + for item in request.input: + if item.role is None: + continue + + if isinstance(item.content, str): + messages.append( + InputMessage( + role=item.role, parts=[Text(content=item.content)] + ) + ) + continue + + if item.content is None: + continue + + parts = [ + Text(content=part.text) + for part in item.content + if part.text is not None + ] + if parts: + messages.append(InputMessage(role=item.role, parts=parts)) + + return messages + + +def _extract_output_parts( + content_blocks: Sequence[_ResponseOutputContentModel], +) -> list["Text"]: + if Text is None: + return [] + + parts: list[Text] = [] + for block in content_blocks: + if block.type == "output_text" and block.text is not None: + parts.append(Text(content=block.text)) + elif block.type == "refusal" and block.refusal is not None: + parts.append(Text(content=block.refusal)) + return parts + + +def _finish_reason_from_status(status: str | None) -> str | None: + # Responses API output items expose lifecycle statuses rather than finish + # reasons. We map the normal terminal state to the GenAI "stop" reason, + # preserve the other terminal statuses verbatim, and drop non-terminal or + # unknown states from the finish_reasons attribute. + if status == "completed": + return "stop" + if status in {"failed", "cancelled", "incomplete"}: + return status + return None + + +def _extract_output_messages_from_model( + result: _ResponsesResultModel, +) -> list["OutputMessage"]: + if OutputMessage is None or Text is None: + return [] + + messages: list[OutputMessage] = [] + for item in result.output: + if item.type != "message": + continue + finish_reason = _finish_reason_from_status(item.status) + if finish_reason is None: + continue + + messages.append( + OutputMessage( + role=item.role if item.role is not None else "assistant", + parts=_extract_output_parts(item.content), + finish_reason=finish_reason, + ) + ) + + return messages + + +def _extract_output_messages( + result: object | _ResponsesResultModel | None, +) -> list["OutputMessage"]: + """Extract output messages from a Responses API result.""" + validated_result = _coerce_response_result(result) + if validated_result is None: + return [] + + return _extract_output_messages_from_model(validated_result) + + +def _extract_finish_reasons_from_model( + result: _ResponsesResultModel, +) -> list[str]: + finish_reasons: list[str] = [] + for item in result.output: + if item.type != "message": + continue + finish_reason = _finish_reason_from_status(item.status) + if finish_reason is not None: + finish_reasons.append(finish_reason) + return finish_reasons + + +def _extract_finish_reasons( + result: object | _ResponsesResultModel | None, +) -> list[str]: + """Extract finish reasons from Responses API output items.""" + validated_result = _coerce_response_result(result) + if validated_result is None: + return [] + + return _extract_finish_reasons_from_model(validated_result) + + +def _extract_output_type(kwargs: Mapping[str, object]) -> str | None: + """Extract output type from Responses API request text.format.""" + request = _validate_request_kwargs(kwargs) + if request is None or request.text is None or request.text.format is None: + return None + + if request.text.format.type == "json_schema": + return "json" + return request.text.format.type + + +def _set_invocation_usage_attributes( + invocation: "LLMInvocation", usage: _UsageModel +) -> None: + if usage.input_tokens is not None: + invocation.input_tokens = usage.input_tokens + else: + invocation.input_tokens = usage.prompt_tokens + + if usage.output_tokens is not None: + invocation.output_tokens = usage.output_tokens + else: + invocation.output_tokens = usage.completion_tokens + + details = ( + usage.input_tokens_details + if usage.input_tokens_details is not None + else usage.prompt_tokens_details + ) + if details is None: + return + + if details.cached_tokens is not None: + invocation.attributes[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] = ( + details.cached_tokens + ) + + if details.cache_creation_input_tokens is not None: + invocation.attributes[GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS] = ( + details.cache_creation_input_tokens + ) + + +def _set_invocation_response_attributes( + invocation: "LLMInvocation", + result: object | None, + capture_content: bool, +) -> None: + # This helper sits at the raw response boundary for instrumentation. Unlike + # the extractor helpers above, it intentionally validates exactly once and + # then fans out to the `_from_model` helpers rather than accepting an + # already-coerced `_ResponsesResultModel`. + if result is None: + return + + validated_result = _validate_response_result(result) + if validated_result is None: + return + + if validated_result.model is not None: + invocation.response_model_name = validated_result.model + + if validated_result.id is not None: + invocation.response_id = validated_result.id + + if validated_result.service_tier is not None: + invocation.attributes[ + OpenAIAttributes.OPENAI_RESPONSE_SERVICE_TIER + ] = validated_result.service_tier + + if validated_result.usage is not None: + _set_invocation_usage_attributes(invocation, validated_result.usage) + + finish_reasons = _extract_finish_reasons_from_model(validated_result) + if finish_reasons: + invocation.finish_reasons = finish_reasons + + if capture_content: + output_messages = _extract_output_messages_from_model(validated_result) + if output_messages: + invocation.output_messages = output_messages diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.pydantic1.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.pydantic1.txt new file mode 100644 index 00000000000..9ca166184dc --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.pydantic1.txt @@ -0,0 +1,55 @@ +# 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. + + +# ******************************** +# WARNING: NOT HERMETIC !!!!!!!!!! +# ******************************** +# +# This "requirements.txt" is installed in conjunction +# with multiple other dependencies in the top-level "tox.ini" +# file. In particular, please see: +# +# openai-pydantic1: {[testenv]test_deps} +# openai-pydantic1: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.pydantic1.txt +# +# This provides additional dependencies, namely: +# +# opentelemetry-api +# opentelemetry-sdk +# opentelemetry-semantic-conventions +# +# ... with a "dev" version based on the latest distribution. + + +# This variant of the requirements aims to test the system using +# the newest supported version of external dependencies with Pydantic 1.x. + +openai==1.109.1 +pydantic==1.10.24 +httpx==0.27.2 +# older jiter is required for PyPy < 3.11 +jiter==0.11.1 +Deprecated==1.2.14 +importlib-metadata==6.11.0 +packaging==24.0 +pytest==7.4.4 +pytest-vcr==1.0.2 +pytest-asyncio==0.21.0 +wrapt==1.16.0 +# test with the latest version of opentelemetry-api, sdk, and semantic conventions + +-e opentelemetry-instrumentation +-e instrumentation-genai/opentelemetry-instrumentation-openai-v2 +-e util/opentelemetry-util-genai diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_extractors.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_extractors.py new file mode 100644 index 00000000000..1cf9a1a70e1 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_extractors.py @@ -0,0 +1,365 @@ +# 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. + +import logging +from types import SimpleNamespace +from unittest import mock + +import pytest + +from opentelemetry.instrumentation.openai_v2 import response_extractors +from opentelemetry.semconv._incubating.attributes import ( + openai_attributes as OpenAIAttributes, +) +from opentelemetry.util.genai.types import LLMInvocation + + +def _validate_compat_model(loaded_module, model_type, value): + return loaded_module._validate_model(model_type, value, "test") + + +@pytest.fixture(scope="module", name="loaded_module") +def _loaded_module_fixture(): + return response_extractors + + +@pytest.fixture( + scope="module", name="gen_ai_usage_cache_creation_input_tokens" +) +def _gen_ai_usage_cache_creation_input_tokens_fixture(loaded_module): + return loaded_module.GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS + + +@pytest.fixture(scope="module", name="gen_ai_usage_cache_read_input_tokens") +def _gen_ai_usage_cache_read_input_tokens_fixture(loaded_module): + return loaded_module.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS + + +def test_extract_system_instruction_returns_text_for_string(loaded_module): + instructions = loaded_module._extract_system_instruction( + {"instructions": "Be concise"} + ) + + assert [part.content for part in instructions] == ["Be concise"] + + +def test_extract_input_messages_supports_string_and_mixed_message_content( + loaded_module, +): + from_string = loaded_module._extract_input_messages({"input": "Hello"}) + from_list = loaded_module._extract_input_messages( + { + "input": [ + {"role": "user", "content": "First"}, + SimpleNamespace( + role="assistant", + content=[ + {"text": "Second"}, + SimpleNamespace(text="Third"), + {"type": "input_image", "image_url": "ignored"}, + ], + ), + {"role": None, "content": "ignored"}, + ] + } + ) + + assert [ + (msg.role, [part.content for part in msg.parts]) for msg in from_string + ] == [("user", ["Hello"])] + assert [ + (msg.role, [part.content for part in msg.parts]) for msg in from_list + ] == [ + ("user", ["First"]), + ("assistant", ["Second", "Third"]), + ] + + +def test_extract_output_messages_maps_parts_and_finish_reasons(loaded_module): + result = SimpleNamespace( + output=[ + SimpleNamespace( + type="message", + role="assistant", + status="completed", + content=[ + SimpleNamespace(type="output_text", text="Done"), + SimpleNamespace(type="refusal", refusal="Cannot comply"), + SimpleNamespace(type="summary", text="ignored"), + ], + ), + SimpleNamespace( + type="message", + status="incomplete", + content=[SimpleNamespace(type="output_text", text="Partial")], + ), + SimpleNamespace( + type="message", + status="queued", + content=[SimpleNamespace(type="output_text", text="Pending")], + ), + SimpleNamespace(type="tool_call", status="completed", content=[]), + ] + ) + + messages = loaded_module._extract_output_messages(result) + + assert [(msg.role, msg.finish_reason) for msg in messages] == [ + ("assistant", "stop"), + ("assistant", "incomplete"), + ] + assert [[part.content for part in msg.parts] for msg in messages] == [ + ["Done", "Cannot comply"], + ["Partial"], + ] + + +def test_extract_finish_reasons_only_reads_message_items(loaded_module): + result = SimpleNamespace( + output=[ + SimpleNamespace(type="message", status="completed"), + SimpleNamespace(type="message", status=None), + SimpleNamespace(type="message", status="in_progress"), + SimpleNamespace(type="tool_call", status="incomplete"), + ] + ) + + assert loaded_module._extract_finish_reasons(result) == ["stop"] + + +def test_extract_output_type_handles_text_format_mapping(loaded_module): + assert ( + loaded_module._extract_output_type( + {"text": {"format": {"type": "json_schema"}}} + ) + == "json" + ) + assert ( + loaded_module._extract_output_type( + {"text": {"format": {"type": "text"}}} + ) + == "text" + ) + assert ( + loaded_module._extract_output_type( + { + "text": SimpleNamespace( + format=SimpleNamespace(type="json_schema") + ) + } + ) + == "json" + ) + assert ( + loaded_module._extract_output_type( + {"text": SimpleNamespace(format=SimpleNamespace(type="text"))} + ) + == "text" + ) + # Invalid request shapes should degrade to no extracted output type rather + # than surfacing validation errors from instrumentation. + assert ( + loaded_module._extract_output_type({"text": {"format": "plain"}}) + is None + ) + assert loaded_module._extract_output_type({"text": "plain"}) is None + + +def test_extractors_handle_missing_genai_types_import(loaded_module): + with ( + mock.patch.object(loaded_module, "Text", None), + mock.patch.object(loaded_module, "InputMessage", None), + mock.patch.object(loaded_module, "OutputMessage", None), + ): + assert ( + loaded_module._extract_system_instruction({"instructions": "hi"}) + == [] + ) + assert loaded_module._extract_input_messages({"input": "hi"}) == [] + assert ( + loaded_module._extract_output_messages( + SimpleNamespace( + output=[SimpleNamespace(type="message", content=[])] + ) + ) + == [] + ) + + +def test_set_invocation_response_attributes_populates_usage_and_metadata( + loaded_module, + gen_ai_usage_cache_creation_input_tokens, + gen_ai_usage_cache_read_input_tokens, +): + invocation = LLMInvocation(request_model="gpt-4o-mini") + result = SimpleNamespace( + model="gpt-4.1", + id="resp_123", + service_tier="scale", + usage=SimpleNamespace( + prompt_tokens=11, + completion_tokens=7, + prompt_tokens_details=SimpleNamespace( + cached_tokens=3, + cache_creation_input_tokens=5, + ), + ), + ) + + loaded_module._set_invocation_response_attributes( + invocation, result, capture_content=False + ) + + assert invocation.response_model_name == "gpt-4.1" + assert invocation.response_id == "resp_123" + assert invocation.input_tokens == 11 + assert invocation.output_tokens == 7 + assert invocation.attributes == { + OpenAIAttributes.OPENAI_RESPONSE_SERVICE_TIER: "scale", + gen_ai_usage_cache_read_input_tokens: 3, + gen_ai_usage_cache_creation_input_tokens: 5, + } + + +def test_set_invocation_response_attributes_accepts_mapping_usage( + loaded_module, + gen_ai_usage_cache_creation_input_tokens, + gen_ai_usage_cache_read_input_tokens, +): + invocation = LLMInvocation(request_model="gpt-4o-mini") + result = SimpleNamespace( + usage={ + "input_tokens": 13, + "output_tokens": 8, + "input_tokens_details": { + "cached_tokens": 2, + "cache_creation_input_tokens": 4, + }, + } + ) + + loaded_module._set_invocation_response_attributes( + invocation, result, capture_content=False + ) + + assert invocation.input_tokens == 13 + assert invocation.output_tokens == 8 + assert invocation.attributes == { + gen_ai_usage_cache_read_input_tokens: 2, + gen_ai_usage_cache_creation_input_tokens: 4, + } + + +def test_set_invocation_response_attributes_populates_output_messages( + loaded_module, +): + invocation = LLMInvocation(request_model="gpt-4o-mini") + result = SimpleNamespace( + output=[ + SimpleNamespace( + type="message", + role="assistant", + status="completed", + content=[SimpleNamespace(type="output_text", text="Done")], + ) + ] + ) + + loaded_module._set_invocation_response_attributes( + invocation, result, capture_content=True + ) + + assert invocation.finish_reasons == ["stop"] + assert [ + (message.role, message.finish_reason) + for message in invocation.output_messages + ] == [("assistant", "stop")] + assert [ + [part.content for part in message.parts] + for message in invocation.output_messages + ] == [["Done"]] + + +def test_prevalidated_response_model_skips_revalidation( + loaded_module, monkeypatch +): + validated_result = _validate_compat_model( + loaded_module, + loaded_module._ResponsesResultModel, + SimpleNamespace( + output=[ + SimpleNamespace( + type="message", + status="completed", + content=[SimpleNamespace(type="output_text", text="Done")], + ) + ] + ), + ) + assert validated_result is not None + + def _unexpected_validation(_result): + raise AssertionError("unexpected response revalidation") + + monkeypatch.setattr( + loaded_module, "_validate_response_result", _unexpected_validation + ) + + assert loaded_module._extract_finish_reasons(validated_result) == ["stop"] + messages = loaded_module._extract_output_messages(validated_result) + assert [part.content for part in messages[0].parts] == ["Done"] + + +@pytest.mark.parametrize( + ("kwargs", "extractor_name"), + [ + ({"instructions": ["not-a-string"]}, "_extract_system_instruction"), + ({"input": 42}, "_extract_input_messages"), + ({"text": {"format": {"type": 42}}}, "_extract_output_type"), + ], +) +def test_request_validation_errors_are_logged_and_ignored( + loaded_module, caplog, kwargs, extractor_name +): + caplog.set_level(logging.DEBUG, logger=loaded_module.__name__) + extractor = getattr(loaded_module, extractor_name) + + result = extractor(kwargs) + + assert result in ([], None) + assert "OpenAI responses extractor validation failed" in caplog.text + + +def test_response_validation_errors_are_logged_and_ignored( + loaded_module, caplog +): + caplog.set_level(logging.DEBUG, logger=loaded_module.__name__) + invocation = LLMInvocation(request_model="gpt-4o-mini") + invalid_result = SimpleNamespace(output=42, usage=42) + + assert loaded_module._extract_output_messages(invalid_result) == [] + assert loaded_module._extract_finish_reasons(invalid_result) == [] + + loaded_module._set_invocation_response_attributes( + invocation, invalid_result, capture_content=True + ) + + assert invocation.response_model_name is None + assert invocation.response_id is None + assert invocation.input_tokens is None + assert invocation.output_tokens is None + assert invocation.finish_reasons is None + assert not invocation.output_messages + assert not invocation.attributes + assert "OpenAI responses extractor validation failed" in caplog.text diff --git a/tox.ini b/tox.ini index b351bf13eee..5b13ed9365a 100644 --- a/tox.ini +++ b/tox.ini @@ -10,6 +10,7 @@ envlist = ; instrumentation-openai py3{9,10,11,12,13,14}-test-instrumentation-openai-v2-{oldest,latest} + py313-test-instrumentation-openai-v2-pydantic1 pypy3-test-instrumentation-openai-v2-{oldest,latest} lint-instrumentation-openai-v2 @@ -482,6 +483,8 @@ deps = # and the latest version of OTel API and SDK openai-latest: {[testenv]test_deps} openai-latest: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.latest.txt + openai-pydantic1: {[testenv]test_deps} + openai-pydantic1: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.pydantic1.txt lint-instrumentation-openai-v2: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/requirements.oldest.txt openai_agents-oldest: -r {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt openai_agents-latest: {[testenv]test_deps} From b9f1d6f2973cd6e8d1e0693af7b8624d1fec1feb Mon Sep 17 00:00:00 2001 From: shuningc Date: Mon, 30 Mar 2026 05:23:05 -0700 Subject: [PATCH 53/78] linting fix --- .../src/opentelemetry/util/genai/handler.py | 31 ++--- .../src/opentelemetry/util/genai/metrics.py | 125 +++++++++++------- .../opentelemetry/util/genai/span_utils.py | 39 ++++++ .../tests/test_handler_metrics.py | 123 ++++++++++++++++- 4 files changed, 248 insertions(+), 70 deletions(-) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py index 858e8a8237c..fc52efb6eca 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py @@ -88,6 +88,7 @@ _get_embedding_span_name, _get_llm_span_name, _get_workflow_span_name, + _maybe_emit_embedding_event, _maybe_emit_llm_event, ) from opentelemetry.util.genai.types import ( @@ -150,9 +151,9 @@ def __init__( schema_url=schema_url, ) - def _record_llm_metrics( + def _record_metrics( self, - invocation: LLMInvocation, + invocation: GenAIInvocation, span: Span | None = None, *, error_type: str | None = None, @@ -165,18 +166,6 @@ def _record_llm_metrics( error_type=error_type, ) - @staticmethod - def _record_embedding_metrics( - invocation: EmbeddingInvocation, - span: Span | None = None, - *, - error_type: str | None = None, - ) -> None: - # Metrics recorder currently supports LLMInvocation fields only. - # Keep embedding metrics as a no-op until dedicated embedding - # metric support is added. - return - def _start(self, invocation: _T) -> _T: """Start a GenAI invocation and create a pending span entry.""" if isinstance(invocation, LLMInvocation): @@ -214,11 +203,12 @@ def _stop(self, invocation: _T) -> _T: try: if isinstance(invocation, LLMInvocation): _apply_llm_finish_attributes(span, invocation) - self._record_llm_metrics(invocation, span) + self._record_metrics(invocation, span) _maybe_emit_llm_event(self._logger, span, invocation) elif isinstance(invocation, EmbeddingInvocation): _apply_embedding_finish_attributes(span, invocation) - self._record_embedding_metrics(invocation, span) + self._record_metrics(invocation, span) + _maybe_emit_embedding_event(self._logger, span, invocation) elif isinstance(invocation, WorkflowInvocation): _apply_workflow_finish_attributes(span, invocation) # TODO: Add workflow metrics when supported @@ -240,17 +230,16 @@ def _fail(self, invocation: _T, error: Error) -> _T: if isinstance(invocation, LLMInvocation): _apply_llm_finish_attributes(span, invocation) _apply_error_attributes(span, error, error_type) - self._record_llm_metrics( - invocation, span, error_type=error_type - ) + self._record_metrics(invocation, span, error_type=error_type) _maybe_emit_llm_event( self._logger, span, invocation, error_type ) elif isinstance(invocation, EmbeddingInvocation): _apply_embedding_finish_attributes(span, invocation) _apply_error_attributes(span, error, error_type) - self._record_embedding_metrics( - invocation, span, error_type=error_type + self._record_metrics(invocation, span, error_type=error_type) + _maybe_emit_embedding_event( + self._logger, span, invocation, error_type ) elif isinstance(invocation, WorkflowInvocation): _apply_workflow_finish_attributes(span, invocation) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py index 075cbe60a1f..c88b0607a66 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py @@ -1,4 +1,4 @@ -"""Helpers for emitting GenAI metrics from LLM invocations.""" +"""Helpers for emitting GenAI metrics from invocations.""" from __future__ import annotations @@ -18,7 +18,7 @@ create_duration_histogram, create_token_histogram, ) -from opentelemetry.util.genai.types import LLMInvocation +from opentelemetry.util.genai.types import GenAIInvocation, LLMInvocation from opentelemetry.util.types import AttributeValue @@ -29,57 +29,69 @@ def __init__(self, meter: Meter): self._duration_histogram: Histogram = create_duration_histogram(meter) self._token_histogram: Histogram = create_token_histogram(meter) + @staticmethod + def _build_attributes( + invocation: GenAIInvocation, + error_type: Optional[str] = None, + ) -> Dict[str, AttributeValue]: + """Build metric attributes from an invocation.""" + attributes: Dict[str, AttributeValue] = {} + + # Set attributes using getattr for fields that may not exist on base class + operation_name = getattr(invocation, "operation_name", None) + if operation_name: + attributes[GenAI.GEN_AI_OPERATION_NAME] = operation_name + + request_model = getattr(invocation, "request_model", None) + if request_model: + attributes[GenAI.GEN_AI_REQUEST_MODEL] = request_model + + provider = getattr(invocation, "provider", None) + if provider: + attributes[GenAI.GEN_AI_PROVIDER_NAME] = provider + + response_model_name = getattr(invocation, "response_model_name", None) + if response_model_name: + attributes[GenAI.GEN_AI_RESPONSE_MODEL] = response_model_name + + server_address = getattr(invocation, "server_address", None) + if server_address: + attributes[server_attributes.SERVER_ADDRESS] = server_address + + server_port = getattr(invocation, "server_port", None) + if server_port is not None: + attributes[server_attributes.SERVER_PORT] = server_port + + metric_attributes = getattr(invocation, "metric_attributes", None) + if metric_attributes: + attributes.update(metric_attributes) + + if error_type: + attributes[error_attributes.ERROR_TYPE] = error_type + + return attributes + def record( self, span: Optional[Span], - invocation: LLMInvocation, + invocation: GenAIInvocation, *, error_type: Optional[str] = None, ) -> None: - """Record duration and token metrics for an invocation if possible.""" + """Record duration and token metrics for an invocation if possible. + + For LLMInvocation: records duration and token (input/output) metrics. + For EmbeddingInvocation: records duration only. + """ # pylint: disable=too-many-branches if span is None: return - token_counts: list[tuple[int, str]] = [] - if invocation.input_tokens is not None: - token_counts.append( - ( - invocation.input_tokens, - GenAI.GenAiTokenTypeValues.INPUT.value, - ) - ) - if invocation.output_tokens is not None: - token_counts.append( - ( - invocation.output_tokens, - GenAI.GenAiTokenTypeValues.OUTPUT.value, - ) - ) + attributes = self._build_attributes(invocation, error_type) - attributes: Dict[str, AttributeValue] = { - GenAI.GEN_AI_OPERATION_NAME: GenAI.GenAiOperationNameValues.CHAT.value - } - if invocation.request_model: - attributes[GenAI.GEN_AI_REQUEST_MODEL] = invocation.request_model - if invocation.provider: - attributes[GenAI.GEN_AI_PROVIDER_NAME] = invocation.provider - if invocation.response_model_name: - attributes[GenAI.GEN_AI_RESPONSE_MODEL] = ( - invocation.response_model_name - ) - if invocation.server_address: - attributes[server_attributes.SERVER_ADDRESS] = ( - invocation.server_address - ) - if invocation.server_port is not None: - attributes[server_attributes.SERVER_PORT] = invocation.server_port - if invocation.metric_attributes: - attributes.update(invocation.metric_attributes) - - # Calculate duration from span timing or invocation monotonic start + # Calculate duration from invocation monotonic start duration_seconds: Optional[float] = None if invocation.monotonic_start_s is not None: duration_seconds = max( @@ -88,8 +100,6 @@ def record( ) span_context = set_span_in_context(span) - if error_type: - attributes[error_attributes.ERROR_TYPE] = error_type if duration_seconds is not None: self._duration_histogram.record( @@ -98,12 +108,31 @@ def record( context=span_context, ) - for token_count, token_type in token_counts: - self._token_histogram.record( - token_count, - attributes=attributes | {GenAI.GEN_AI_TOKEN_TYPE: token_type}, - context=span_context, - ) + # Only record token metrics for LLMInvocation + if isinstance(invocation, LLMInvocation): + token_counts: list[tuple[int, str]] = [] + if invocation.input_tokens is not None: + token_counts.append( + ( + invocation.input_tokens, + GenAI.GenAiTokenTypeValues.INPUT.value, + ) + ) + if invocation.output_tokens is not None: + token_counts.append( + ( + invocation.output_tokens, + GenAI.GenAiTokenTypeValues.OUTPUT.value, + ) + ) + + for token_count, token_type in token_counts: + self._token_histogram.record( + token_count, + attributes=attributes + | {GenAI.GEN_AI_TOKEN_TYPE: token_type}, + context=span_context, + ) __all__ = ["InvocationMetricsRecorder"] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py index 0a82462c1bb..ec965d756bf 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py @@ -235,6 +235,44 @@ def _maybe_emit_llm_event( logger.emit(event) +def _maybe_emit_embedding_event( + logger: Logger | None, + span: Span, + invocation: EmbeddingInvocation, + error_type: str | None = None, +) -> None: + """Emit a gen_ai.client.inference.operation.details event to the logger. + + This function creates a LogRecord event following the semantic convention + for gen_ai.client.inference.operation.details as specified in the GenAI + event semantic conventions. + + For more details, see the semantic convention documentation: + https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md#event-eventgen_aiclientinferenceoperationdetails + """ + if not is_experimental_mode() or not should_emit_event() or logger is None: + return + + # Build event attributes by reusing the attribute getter functions + attributes: dict[str, Any] = {} + attributes.update(_get_embedding_common_attributes(invocation)) + attributes.update(_get_embedding_request_attributes(invocation)) + attributes.update(_get_embedding_response_attributes(invocation)) + + # Add error.type if operation ended in error + if error_type is not None: + attributes[error_attributes.ERROR_TYPE] = error_type + + # Create and emit the event + context = set_span_in_context(span, get_current()) + event = LogRecord( + event_name="gen_ai.client.embedding.operation.details", + attributes=attributes, + context=context, + ) + logger.emit(event) + + def _apply_llm_finish_attributes( span: Span, invocation: LLMInvocation ) -> None: @@ -408,6 +446,7 @@ def _get_embedding_response_attributes( "_maybe_emit_llm_event", "_get_workflow_common_attributes", "_apply_workflow_finish_attributes", + "_maybe_emit_embedding_event", "_apply_embedding_finish_attributes", "_get_embedding_common_attributes", "_get_embedding_request_attributes", diff --git a/util/opentelemetry-util-genai/tests/test_handler_metrics.py b/util/opentelemetry-util-genai/tests/test_handler_metrics.py index b45383abfe7..af38eac6636 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_metrics.py +++ b/util/opentelemetry-util-genai/tests/test_handler_metrics.py @@ -9,7 +9,11 @@ from opentelemetry.semconv.schemas import Schemas from opentelemetry.test.test_base import TestBase from opentelemetry.util.genai.handler import TelemetryHandler -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import ( + EmbeddingInvocation, + Error, + LLMInvocation, +) _DEFAULT_SCHEMA_URL = Schemas.V1_37_0.value @@ -181,3 +185,120 @@ def _assert_metric_scope_schema_urls( self.assertEqual( scope_metric.scope.schema_url, expected_schema_url ) + + def test_stop_embedding_records_duration_only(self) -> None: + """Verify embedding invocations record duration but not token metrics.""" + handler = TelemetryHandler( + tracer_provider=self.tracer_provider, + meter_provider=self.meter_provider, + ) + invocation = EmbeddingInvocation( + request_model="embed-model", provider="embed-prov" + ) + invocation.input_tokens = 100 # Should NOT be recorded as token metric + # Patch default_timer during start to ensure monotonic_start_s + with patch("timeit.default_timer", return_value=1000.0): + handler.start(invocation) + + # Simulate 1.5 seconds of elapsed monotonic time + with patch("timeit.default_timer", return_value=1001.5): + handler.stop(invocation) + + self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) + metrics = self._harvest_metrics() + + # Duration should be recorded + self.assertIn("gen_ai.client.operation.duration", metrics) + duration_points = metrics["gen_ai.client.operation.duration"] + self.assertEqual(len(duration_points), 1) + duration_point = duration_points[0] + self.assertEqual( + duration_point.attributes[GenAI.GEN_AI_OPERATION_NAME], + GenAI.GenAiOperationNameValues.EMBEDDINGS.value, + ) + self.assertEqual( + duration_point.attributes[GenAI.GEN_AI_REQUEST_MODEL], + "embed-model", + ) + self.assertEqual( + duration_point.attributes[GenAI.GEN_AI_PROVIDER_NAME], "embed-prov" + ) + self.assertAlmostEqual(duration_point.sum, 1.5, places=3) + + # Token metrics should NOT be recorded for embedding + self.assertNotIn("gen_ai.client.token.usage", metrics) + + def test_stop_embedding_records_duration_with_additional_attributes( + self, + ) -> None: + """Verify embedding metrics include server and custom attributes.""" + handler = TelemetryHandler( + tracer_provider=self.tracer_provider, + meter_provider=self.meter_provider, + ) + invocation = EmbeddingInvocation( + request_model="embed-model", + provider="embed-prov", + server_address="embed.server.com", + server_port=8080, + ) + handler.start(invocation) + invocation.metric_attributes = {"custom.embed.attr": "embed_value"} + invocation.response_model_name = "embed-response-model" + handler.stop(invocation) + + self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) + metrics = self._harvest_metrics() + + self.assertIn("gen_ai.client.operation.duration", metrics) + duration_points = metrics["gen_ai.client.operation.duration"] + self.assertEqual(len(duration_points), 1) + duration_point = duration_points[0] + + self.assertEqual( + duration_point.attributes["server.address"], "embed.server.com" + ) + self.assertEqual(duration_point.attributes["server.port"], 8080) + self.assertEqual( + duration_point.attributes["custom.embed.attr"], "embed_value" + ) + self.assertEqual( + duration_point.attributes[GenAI.GEN_AI_RESPONSE_MODEL], + "embed-response-model", + ) + + def test_fail_embedding_records_error_and_duration(self) -> None: + """Verify embedding failure records error type and duration.""" + handler = TelemetryHandler( + tracer_provider=self.tracer_provider, + meter_provider=self.meter_provider, + ) + invocation = EmbeddingInvocation( + request_model="embed-err-model", provider="embed-prov" + ) + with patch("timeit.default_timer", return_value=3000.0): + handler.start(invocation) + + error = Error(message="embedding failed", type=RuntimeError) + with patch("timeit.default_timer", return_value=3002.5): + handler.fail(invocation, error) + + self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) + metrics = self._harvest_metrics() + + self.assertIn("gen_ai.client.operation.duration", metrics) + duration_points = metrics["gen_ai.client.operation.duration"] + self.assertEqual(len(duration_points), 1) + duration_point = duration_points[0] + + self.assertEqual( + duration_point.attributes.get("error.type"), "RuntimeError" + ) + self.assertEqual( + duration_point.attributes.get(GenAI.GEN_AI_REQUEST_MODEL), + "embed-err-model", + ) + self.assertAlmostEqual(duration_point.sum, 2.5, places=3) + + # Token metrics should NOT be recorded for embedding even on failure + self.assertNotIn("gen_ai.client.token.usage", metrics) From db0cafc933db9d4aea7a045b8cbaf1cdcb6651b4 Mon Sep 17 00:00:00 2001 From: shuningc Date: Mon, 30 Mar 2026 05:48:27 -0700 Subject: [PATCH 54/78] Updating changelog --- util/opentelemetry-util-genai/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index 40b05bb3594..47d9015197f 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - +- Add metrics support for EmbeddingInvocation + ([#5022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/5022)) - Add support for workflow in genAI utils handler. ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4366](#4366)) - Enrich ToolCall type, breaking change: usage of ToolCall class renamed to ToolCallRequest From f4b90f24538f371c172c8e195de1b7dc885e69a2 Mon Sep 17 00:00:00 2001 From: shuningc Date: Mon, 30 Mar 2026 05:53:26 -0700 Subject: [PATCH 55/78] Updating changelog PR number --- util/opentelemetry-util-genai/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index 47d9015197f..c4d57c28b68 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Add metrics support for EmbeddingInvocation + ([#4377](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4377)) - Add metrics support for EmbeddingInvocation ([#5022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/5022)) - Add support for workflow in genAI utils handler. From 4ce9ee183a6f8985db7fef7a472c4c398290b654 Mon Sep 17 00:00:00 2001 From: shuningc Date: Wed, 1 Apr 2026 10:13:57 -0700 Subject: [PATCH 56/78] Removing embedding events emission --- .../src/opentelemetry/util/genai/handler.py | 4 -- .../opentelemetry/util/genai/span_utils.py | 39 ------------------- 2 files changed, 43 deletions(-) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py index fc52efb6eca..5fa2f7ad323 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py @@ -208,7 +208,6 @@ def _stop(self, invocation: _T) -> _T: elif isinstance(invocation, EmbeddingInvocation): _apply_embedding_finish_attributes(span, invocation) self._record_metrics(invocation, span) - _maybe_emit_embedding_event(self._logger, span, invocation) elif isinstance(invocation, WorkflowInvocation): _apply_workflow_finish_attributes(span, invocation) # TODO: Add workflow metrics when supported @@ -238,9 +237,6 @@ def _fail(self, invocation: _T, error: Error) -> _T: _apply_embedding_finish_attributes(span, invocation) _apply_error_attributes(span, error, error_type) self._record_metrics(invocation, span, error_type=error_type) - _maybe_emit_embedding_event( - self._logger, span, invocation, error_type - ) elif isinstance(invocation, WorkflowInvocation): _apply_workflow_finish_attributes(span, invocation) _apply_error_attributes(span, error, error_type) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py index ec965d756bf..0a82462c1bb 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py @@ -235,44 +235,6 @@ def _maybe_emit_llm_event( logger.emit(event) -def _maybe_emit_embedding_event( - logger: Logger | None, - span: Span, - invocation: EmbeddingInvocation, - error_type: str | None = None, -) -> None: - """Emit a gen_ai.client.inference.operation.details event to the logger. - - This function creates a LogRecord event following the semantic convention - for gen_ai.client.inference.operation.details as specified in the GenAI - event semantic conventions. - - For more details, see the semantic convention documentation: - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md#event-eventgen_aiclientinferenceoperationdetails - """ - if not is_experimental_mode() or not should_emit_event() or logger is None: - return - - # Build event attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_embedding_common_attributes(invocation)) - attributes.update(_get_embedding_request_attributes(invocation)) - attributes.update(_get_embedding_response_attributes(invocation)) - - # Add error.type if operation ended in error - if error_type is not None: - attributes[error_attributes.ERROR_TYPE] = error_type - - # Create and emit the event - context = set_span_in_context(span, get_current()) - event = LogRecord( - event_name="gen_ai.client.embedding.operation.details", - attributes=attributes, - context=context, - ) - logger.emit(event) - - def _apply_llm_finish_attributes( span: Span, invocation: LLMInvocation ) -> None: @@ -446,7 +408,6 @@ def _get_embedding_response_attributes( "_maybe_emit_llm_event", "_get_workflow_common_attributes", "_apply_workflow_finish_attributes", - "_maybe_emit_embedding_event", "_apply_embedding_finish_attributes", "_get_embedding_common_attributes", "_get_embedding_request_attributes", From 80bd373e0d178b74f53c1a03ab058ef6628db560 Mon Sep 17 00:00:00 2001 From: shuningc Date: Tue, 7 Apr 2026 16:53:58 -0700 Subject: [PATCH 57/78] Refatoring and adding input token metric for Embedding invocation --- .../src/opentelemetry/util/genai/metrics.py | 56 +++++++++---------- .../src/opentelemetry/util/genai/types.py | 26 ++++----- .../tests/test_handler_metrics.py | 41 ++++++++++++-- 3 files changed, 73 insertions(+), 50 deletions(-) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py index c88b0607a66..e2ebad64096 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py @@ -18,7 +18,11 @@ create_duration_histogram, create_token_histogram, ) -from opentelemetry.util.genai.types import GenAIInvocation, LLMInvocation +from opentelemetry.util.genai.types import ( + EmbeddingInvocation, + GenAIInvocation, + LLMInvocation, +) from opentelemetry.util.types import AttributeValue @@ -37,18 +41,15 @@ def _build_attributes( """Build metric attributes from an invocation.""" attributes: Dict[str, AttributeValue] = {} - # Set attributes using getattr for fields that may not exist on base class - operation_name = getattr(invocation, "operation_name", None) - if operation_name: - attributes[GenAI.GEN_AI_OPERATION_NAME] = operation_name + if invocation.operation_name: + attributes[GenAI.GEN_AI_OPERATION_NAME] = invocation.operation_name request_model = getattr(invocation, "request_model", None) if request_model: attributes[GenAI.GEN_AI_REQUEST_MODEL] = request_model - provider = getattr(invocation, "provider", None) - if provider: - attributes[GenAI.GEN_AI_PROVIDER_NAME] = provider + if invocation.provider: + attributes[GenAI.GEN_AI_PROVIDER_NAME] = invocation.provider response_model_name = getattr(invocation, "response_model_name", None) if response_model_name: @@ -62,9 +63,8 @@ def _build_attributes( if server_port is not None: attributes[server_attributes.SERVER_PORT] = server_port - metric_attributes = getattr(invocation, "metric_attributes", None) - if metric_attributes: - attributes.update(metric_attributes) + if invocation.metric_attributes: + attributes.update(invocation.metric_attributes) if error_type: attributes[error_attributes.ERROR_TYPE] = error_type @@ -108,29 +108,27 @@ def record( context=span_context, ) - # Only record token metrics for LLMInvocation - if isinstance(invocation, LLMInvocation): - token_counts: list[tuple[int, str]] = [] + # Record token metrics for LLMInvocation and EmbeddingInvocation + if isinstance(invocation, (LLMInvocation, EmbeddingInvocation)): if invocation.input_tokens is not None: - token_counts.append( - ( - invocation.input_tokens, - GenAI.GenAiTokenTypeValues.INPUT.value, - ) - ) - if invocation.output_tokens is not None: - token_counts.append( - ( - invocation.output_tokens, - GenAI.GenAiTokenTypeValues.OUTPUT.value, - ) + self._token_histogram.record( + invocation.input_tokens, + attributes=attributes + | { + GenAI.GEN_AI_TOKEN_TYPE: GenAI.GenAiTokenTypeValues.INPUT.value + }, + context=span_context, ) - for token_count, token_type in token_counts: + # Only LLMInvocation has output tokens + if isinstance(invocation, LLMInvocation): + if invocation.output_tokens is not None: self._token_histogram.record( - token_count, + invocation.output_tokens, attributes=attributes - | {GenAI.GEN_AI_TOKEN_TYPE: token_type}, + | { + GenAI.GEN_AI_TOKEN_TYPE: GenAI.GenAiTokenTypeValues.OUTPUT.value + }, context=span_context, ) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py index 6d59f03bf5e..35f8473f0c2 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py @@ -256,9 +256,18 @@ def _new_str_any_dict() -> dict[str, Any]: @dataclass class GenAIInvocation: + operation_name: str = "" + provider: str | None = None context_token: ContextToken | None = None span: Span | None = None attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) + metric_attributes: dict[str, Any] = field( + default_factory=_new_str_any_dict + ) + """ + Additional attributes to set on metrics. Must be of a low cardinality. + These attributes will not be set on spans or events. + """ error_type: str | None = None monotonic_start_s: float | None = None @@ -319,13 +328,6 @@ class LLMInvocation(GenAIInvocation): Additional attributes to set on spans and/or events. These attributes will not be set on metrics. """ - metric_attributes: dict[str, Any] = field( - default_factory=_new_str_any_dict - ) - """ - Additional attributes to set on metrics. Must be of a low cardinality. - These attributes will not be set on spans or events. - """ temperature: float | None = None top_p: float | None = None frequency_penalty: float | None = None @@ -364,14 +366,6 @@ class EmbeddingInvocation(GenAIInvocation): will not be set on metrics. """ - metric_attributes: dict[str, Any] = field( - default_factory=_new_str_any_dict - ) - """ - Additional attributes to set on metrics. Must be of a low cardinality. - These attributes will not be set on spans or events. - """ - @dataclass() class ToolCall(GenAIInvocation): @@ -399,6 +393,8 @@ class ToolCall(GenAIInvocation): - error.type: Error type if operation failed (Conditionally Required) """ + operation_name: str = GenAI.GenAiOperationNameValues.EXECUTE_TOOL.value + # Message identification fields (same as ToolCallRequest) # Note: These are required fields but must have defaults due to dataclass inheritance name: str = "" diff --git a/util/opentelemetry-util-genai/tests/test_handler_metrics.py b/util/opentelemetry-util-genai/tests/test_handler_metrics.py index af38eac6636..3b16a1ec1d9 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_metrics.py +++ b/util/opentelemetry-util-genai/tests/test_handler_metrics.py @@ -186,8 +186,8 @@ def _assert_metric_scope_schema_urls( scope_metric.scope.schema_url, expected_schema_url ) - def test_stop_embedding_records_duration_only(self) -> None: - """Verify embedding invocations record duration but not token metrics.""" + def test_stop_embedding_records_duration_and_tokens(self) -> None: + """Verify embedding invocations record duration and input token metrics.""" handler = TelemetryHandler( tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, @@ -195,7 +195,7 @@ def test_stop_embedding_records_duration_only(self) -> None: invocation = EmbeddingInvocation( request_model="embed-model", provider="embed-prov" ) - invocation.input_tokens = 100 # Should NOT be recorded as token metric + invocation.input_tokens = 100 # Patch default_timer during start to ensure monotonic_start_s with patch("timeit.default_timer", return_value=1000.0): handler.start(invocation) @@ -225,8 +225,16 @@ def test_stop_embedding_records_duration_only(self) -> None: ) self.assertAlmostEqual(duration_point.sum, 1.5, places=3) - # Token metrics should NOT be recorded for embedding - self.assertNotIn("gen_ai.client.token.usage", metrics) + # Token metrics should be recorded for embedding (input only) + self.assertIn("gen_ai.client.token.usage", metrics) + token_points = metrics["gen_ai.client.token.usage"] + self.assertEqual(len(token_points), 1) # Only input tokens + token_point = token_points[0] + self.assertEqual( + token_point.attributes[GenAI.GEN_AI_TOKEN_TYPE], + GenAI.GenAiTokenTypeValues.INPUT.value, + ) + self.assertAlmostEqual(token_point.sum, 100.0, places=3) def test_stop_embedding_records_duration_with_additional_attributes( self, @@ -300,5 +308,26 @@ def test_fail_embedding_records_error_and_duration(self) -> None: ) self.assertAlmostEqual(duration_point.sum, 2.5, places=3) - # Token metrics should NOT be recorded for embedding even on failure + # Token metrics should NOT be recorded when input_tokens is not set + self.assertNotIn("gen_ai.client.token.usage", metrics) + + def test_stop_embedding_without_tokens(self) -> None: + """Verify embedding without input_tokens does not record token metrics.""" + handler = TelemetryHandler( + tracer_provider=self.tracer_provider, + meter_provider=self.meter_provider, + ) + invocation = EmbeddingInvocation( + request_model="embed-model", provider="embed-prov" + ) + # input_tokens is not set + handler.start(invocation) + handler.stop(invocation) + + metrics = self._harvest_metrics() + + # Duration should be recorded + self.assertIn("gen_ai.client.operation.duration", metrics) + + # Token metrics should NOT be recorded when input_tokens is not set self.assertNotIn("gen_ai.client.token.usage", metrics) From 68d328f01e0959305768787a023962b3a54336ce Mon Sep 17 00:00:00 2001 From: shuningc Date: Tue, 7 Apr 2026 17:10:36 -0700 Subject: [PATCH 58/78] Merging and removing unused import --- .../src/opentelemetry/util/genai/handler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py index 5fa2f7ad323..8207af977c0 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py @@ -88,7 +88,6 @@ _get_embedding_span_name, _get_llm_span_name, _get_workflow_span_name, - _maybe_emit_embedding_event, _maybe_emit_llm_event, ) from opentelemetry.util.genai.types import ( From 322332f0cc33337bd4becfbe3d0b252a2224f9aa Mon Sep 17 00:00:00 2001 From: Marylia Gutierrez Date: Wed, 8 Apr 2026 10:46:36 -0400 Subject: [PATCH 59/78] [chore]: update readme (#4401) Group all emeritus into one to keep consistent for script cleanup --- README.md | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 355493db1e5..fee84f5bba3 100644 --- a/README.md +++ b/README.md @@ -134,22 +134,17 @@ For more information about the maintainer role, see the [community repository](h For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver). -### Emeritus Maintainers - -- [Alex Boten](https://github.com/codeboten) -- [Diego Hurtado](https://github.com/ocelotl) -- [Owais Lone](https://github.com/owais) -- [Shalev Roda](https://github.com/shalevr) -- [Yusuke Tsutsumi](https://github.com/toumorokoshi) - -For more information about the emeritus role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager). - -### Emeritus Approvers - -- [Ashutosh Goel](https://github.com/ashu658) -- [Nathaniel Ruiz Nowell](https://github.com/NathanielRN) -- [Nikolay Sokolik](https://github.com/nikosokolik) -- [Nikolay Sokolik](https://github.com/oxeye-nikolay) +### Emeritus + +- [Alex Boten](https://github.com/codeboten), Maintainer +- [Ashutosh Goel](https://github.com/ashu658), Approver +- [Diego Hurtado](https://github.com/ocelotl), Maintainer +- [Nathaniel Ruiz Nowell](https://github.com/NathanielRN), Approver +- [Nikolay Sokolik](https://github.com/nikosokolik), Approver +- [Nikolay Sokolik](https://github.com/oxeye-nikolay), Approver +- [Owais Lone](https://github.com/owais), Maintainer +- [Shalev Roda](https://github.com/shalevr), Maintainer +- [Yusuke Tsutsumi](https://github.com/toumorokoshi), Maintainer For more information about the emeritus role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager). From bef525110921048fc58a238f6cb970eba409de0d Mon Sep 17 00:00:00 2001 From: "otelbot[bot]" <197425009+otelbot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:41:49 +0200 Subject: [PATCH 60/78] Update version to 1.42.0.dev/0.63b0.dev (#4407) Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com> --- CHANGELOG.md | 2 + _template/version.py | 2 +- eachdist.ini | 4 +- .../gcp_credential_provider/version.py | 2 +- .../prometheus_remote_write/version.py | 2 +- .../pyproject.toml | 2 +- .../exporter/richconsole/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/aio_pika/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_client/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/aiohttp_server/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiokafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aiopg/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/asgi/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncclick/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncio/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/asyncpg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/aws_lambda/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/boto3sqs/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/botocore/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/cassandra/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/celery/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/click/version.py | 2 +- .../pyproject.toml | 2 +- .../confluent_kafka/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/dbapi/version.py | 2 +- .../pyproject.toml | 10 +- .../instrumentation/django/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/elasticsearch/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/falcon/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/fastapi/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/flask/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/grpc/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/httpx/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/jinja2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/kafka/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/logging/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysql/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/mysqlclient/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/pika/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/psycopg2/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymemcache/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymongo/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymssql/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/pymysql/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/pyramid/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/redis/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/remoulade/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/requests/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlalchemy/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/sqlite3/version.py | 2 +- .../pyproject.toml | 8 +- .../instrumentation/starlette/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/system_metrics/version.py | 2 +- .../pyproject.toml | 2 +- .../instrumentation/threading/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/tornado/version.py | 2 +- .../pyproject.toml | 4 +- .../instrumentation/tortoiseorm/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/urllib3/version.py | 2 +- .../pyproject.toml | 6 +- .../instrumentation/wsgi/version.py | 2 +- .../pyproject.toml | 100 ++++++++-------- .../contrib-instrumentations/version.py | 2 +- opentelemetry-distro/pyproject.toml | 4 +- .../src/opentelemetry/distro/version.py | 2 +- opentelemetry-instrumentation/pyproject.toml | 2 +- .../instrumentation/bootstrap_gen.py | 108 +++++++++--------- .../opentelemetry/instrumentation/version.py | 2 +- .../processor/baggage/version.py | 2 +- .../propagators/ot_trace/version.py | 2 +- .../resource/detector/containerid/version.py | 2 +- .../src/opentelemetry/util/http/version.py | 2 +- 118 files changed, 288 insertions(+), 286 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9e48cd6df8..9c108e893e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 > Use [this search for a list of all CHANGELOG.md files in this repo](https://github.com/search?q=repo%3Aopen-telemetry%2Fopentelemetry-python-contrib+path%3A**%2FCHANGELOG.md&type=code). ## Unreleased + +## Version 1.41.0/0.62b0 (2026-04-09) ### Added diff --git a/_template/version.py b/_template/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/_template/version.py +++ b/_template/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/eachdist.ini b/eachdist.ini index 59467a8aedf..1304a411348 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -16,7 +16,7 @@ sortfirst= ext/* [stable] -version=1.41.0.dev +version=1.42.0.dev packages= opentelemetry-sdk @@ -35,7 +35,7 @@ packages= opentelemetry-exporter-credential-provider-gcp [prerelease] -version=0.62b0.dev +version=0.63b0.dev packages= all diff --git a/exporter/opentelemetry-exporter-credential-provider-gcp/src/opentelemetry/gcp_credential_provider/version.py b/exporter/opentelemetry-exporter-credential-provider-gcp/src/opentelemetry/gcp_credential_provider/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/exporter/opentelemetry-exporter-credential-provider-gcp/src/opentelemetry/gcp_credential_provider/version.py +++ b/exporter/opentelemetry-exporter-credential-provider-gcp/src/opentelemetry/gcp_credential_provider/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/src/opentelemetry/exporter/prometheus_remote_write/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 57c16a81d01..64f3589520d 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ dependencies = [ "opentelemetry-api ~= 1.12", "opentelemetry-sdk ~= 1.12", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "rich>=10.0.0", ] diff --git a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py +++ b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 2d6368350c8..7eb7f04f2ce 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index 7b851a402b5..ef895020ab6 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py index 1fbc44b3e30..edf0d60188f 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index 1a8ad807b1f..779db188c4b 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml index 3bd3cc2551d..9c9827a3c0e 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.27", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "typing_extensions ~= 4.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index cc3d33c23f9..13bf30b54cd 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-dbapi == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-dbapi == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index 982de74d468..24e3debff17 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -28,9 +28,9 @@ classifiers = [ dependencies = [ "asgiref ~= 3.0", "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml index ffc9999d122..b2a3e5c397b 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt ~= 1.0", "typing_extensions ~= 4.12", ] diff --git a/instrumentation/opentelemetry-instrumentation-asyncclick/src/opentelemetry/instrumentation/asyncclick/version.py b/instrumentation/opentelemetry-instrumentation-asyncclick/src/opentelemetry/instrumentation/asyncclick/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncclick/src/opentelemetry/instrumentation/asyncclick/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncclick/src/opentelemetry/instrumentation/asyncclick/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index bb7196168a9..e30dc7821c2 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.14", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index adb72936a35..589fd11903e 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index 3afe9b2131f..ba0b4e3e422 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index 3df8ab78fb1..f373fd189bf 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index 00cab57e778..fa5e8850f77 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.37", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "opentelemetry-propagator-aws-xray ~= 1.0", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index d919e124699..60200cce006 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py +++ b/instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index 7a105fa4399..b60271f42b9 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml index bfa83b6f895..3e36f50e3e5 100644 --- a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py +++ b/instrumentation/opentelemetry-instrumentation-click/src/opentelemetry/instrumentation/click/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 2f1ea1e380b..87ac6c59669 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-instrumentation == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", "opentelemetry-api ~= 1.12", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index 6fd52f5ff09..db9d0b053d0 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py index 46b492f2555..d21c60d9185 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index 35df0c42dec..d0d5090ab3b 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -27,15 +27,15 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-wsgi == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-wsgi == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", ] [project.optional-dependencies] asgi = [ - "opentelemetry-instrumentation-asgi == 0.62b0.dev", + "opentelemetry-instrumentation-asgi == 0.63b0.dev", ] instruments = [ "django >= 2.0", diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index c30509f28f0..8b44950fc9a 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index 460e50ba857..c4a59473d52 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -27,10 +27,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-wsgi == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-wsgi == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", "packaging >= 20.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index ca9450f6dbe..7159b2a01c5 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -27,10 +27,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-asgi == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-asgi == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index ff7d3b60e79..08a7366e3f0 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -27,10 +27,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-wsgi == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-wsgi == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", "packaging >= 21.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index b5b1a3cab05..adcfa7afd79 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 0ee95e83108..7b356b50789 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index c9ae526c74b..ed6cb19b9fc 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py +++ b/instrumentation/opentelemetry-instrumentation-jinja2/src/opentelemetry/instrumentation/jinja2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index f84b48299bb..ac883738d47 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.5", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index 71a9b31e4e8..de216965c81 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py index 46b492f2555..d21c60d9185 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index bd143731bc6..e780d5ab297 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-dbapi == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-dbapi == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index ac54f38f844..e732ccb1491 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-dbapi == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-dbapi == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 875e0556804..5679a9799c6 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-instrumentation == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", "opentelemetry-api ~= 1.5", "packaging >= 20.0", "wrapt >= 1.0.0, < 3.0.0", diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 910619d3894..322e86d2811 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-dbapi == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-dbapi == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index c18c5bb977b..601b6489184 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-dbapi == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-dbapi == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index 0d2217d6a68..73c9829a31f 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index f714361b0e8..a58af7ec205 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml index 317b68f5ad3..c29c392bebc 100644 --- a/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-dbapi == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-dbapi == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymssql/src/opentelemetry/instrumentation/pymssql/version.py b/instrumentation/opentelemetry-instrumentation-pymssql/src/opentelemetry/instrumentation/pymssql/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-pymssql/src/opentelemetry/instrumentation/pymssql/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymssql/src/opentelemetry/instrumentation/pymssql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index 1310aec93f7..9dfc439e009 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-dbapi == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-dbapi == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py +++ b/instrumentation/opentelemetry-instrumentation-pymysql/src/opentelemetry/instrumentation/pymysql/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index b5840991fc6..7d1450e83f0 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -28,10 +28,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-wsgi == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-wsgi == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index 77a2496ba65..2277a7f8a50 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.12.1", ] diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index 9aac495d337..5e00fa48cfc 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py +++ b/instrumentation/opentelemetry-instrumentation-remoulade/src/opentelemetry/instrumentation/remoulade/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index 445e42e327d..d0ddab1e3cd 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index c6a4c570b53..1e69d56ac62 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "packaging >= 21.0", "wrapt >= 1.11.2", ] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index eb08c3f8b93..b941f926e26 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-dbapi == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-dbapi == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py index 46b492f2555..d21c60d9185 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" _instruments = tuple() diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 96fa61939bd..518014039bd 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -27,10 +27,10 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-instrumentation-asgi == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-instrumentation-asgi == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 207f1a0307e..0d2aa6d658b 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-instrumentation == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", "opentelemetry-api ~= 1.11", "psutil >= 5.9.0, < 8", ] diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/src/opentelemetry/instrumentation/system_metrics/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index ab3f7bc5954..66e2a1b8d9f 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py +++ b/instrumentation/opentelemetry-instrumentation-threading/src/opentelemetry/instrumentation/threading/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index 3dea8189e66..04890fa6077 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -26,9 +26,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index c6fb4439b73..5c0ea288b8e 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -27,8 +27,8 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/src/opentelemetry/instrumentation/tortoiseorm/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 6cafe029351..258e28848db 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index 6fc08d3c8a8..0e3e2c5f990 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", ] diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index a63f5eee26f..6fcdeb58684 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", - "opentelemetry-semantic-conventions == 0.62b0.dev", - "opentelemetry-util-http == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", + "opentelemetry-util-http == 0.63b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 04cce7f6e1d..76713cfe12d 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -30,56 +30,56 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-instrumentation-aio-pika==0.62b0.dev", - "opentelemetry-instrumentation-aiohttp-client==0.62b0.dev", - "opentelemetry-instrumentation-aiohttp-server==0.62b0.dev", - "opentelemetry-instrumentation-aiokafka==0.62b0.dev", - "opentelemetry-instrumentation-aiopg==0.62b0.dev", - "opentelemetry-instrumentation-asgi==0.62b0.dev", - "opentelemetry-instrumentation-asyncclick==0.62b0.dev", - "opentelemetry-instrumentation-asyncio==0.62b0.dev", - "opentelemetry-instrumentation-asyncpg==0.62b0.dev", - "opentelemetry-instrumentation-aws-lambda==0.62b0.dev", - "opentelemetry-instrumentation-boto3sqs==0.62b0.dev", - "opentelemetry-instrumentation-botocore==0.62b0.dev", - "opentelemetry-instrumentation-cassandra==0.62b0.dev", - "opentelemetry-instrumentation-celery==0.62b0.dev", - "opentelemetry-instrumentation-click==0.62b0.dev", - "opentelemetry-instrumentation-confluent-kafka==0.62b0.dev", - "opentelemetry-instrumentation-dbapi==0.62b0.dev", - "opentelemetry-instrumentation-django==0.62b0.dev", - "opentelemetry-instrumentation-elasticsearch==0.62b0.dev", - "opentelemetry-instrumentation-falcon==0.62b0.dev", - "opentelemetry-instrumentation-fastapi==0.62b0.dev", - "opentelemetry-instrumentation-flask==0.62b0.dev", - "opentelemetry-instrumentation-grpc==0.62b0.dev", - "opentelemetry-instrumentation-httpx==0.62b0.dev", - "opentelemetry-instrumentation-jinja2==0.62b0.dev", - "opentelemetry-instrumentation-kafka-python==0.62b0.dev", - "opentelemetry-instrumentation-logging==0.62b0.dev", - "opentelemetry-instrumentation-mysql==0.62b0.dev", - "opentelemetry-instrumentation-mysqlclient==0.62b0.dev", - "opentelemetry-instrumentation-pika==0.62b0.dev", - "opentelemetry-instrumentation-psycopg==0.62b0.dev", - "opentelemetry-instrumentation-psycopg2==0.62b0.dev", - "opentelemetry-instrumentation-pymemcache==0.62b0.dev", - "opentelemetry-instrumentation-pymongo==0.62b0.dev", - "opentelemetry-instrumentation-pymssql==0.62b0.dev", - "opentelemetry-instrumentation-pymysql==0.62b0.dev", - "opentelemetry-instrumentation-pyramid==0.62b0.dev", - "opentelemetry-instrumentation-redis==0.62b0.dev", - "opentelemetry-instrumentation-remoulade==0.62b0.dev", - "opentelemetry-instrumentation-requests==0.62b0.dev", - "opentelemetry-instrumentation-sqlalchemy==0.62b0.dev", - "opentelemetry-instrumentation-sqlite3==0.62b0.dev", - "opentelemetry-instrumentation-starlette==0.62b0.dev", - "opentelemetry-instrumentation-system-metrics==0.62b0.dev", - "opentelemetry-instrumentation-threading==0.62b0.dev", - "opentelemetry-instrumentation-tornado==0.62b0.dev", - "opentelemetry-instrumentation-tortoiseorm==0.62b0.dev", - "opentelemetry-instrumentation-urllib==0.62b0.dev", - "opentelemetry-instrumentation-urllib3==0.62b0.dev", - "opentelemetry-instrumentation-wsgi==0.62b0.dev", + "opentelemetry-instrumentation-aio-pika==0.63b0.dev", + "opentelemetry-instrumentation-aiohttp-client==0.63b0.dev", + "opentelemetry-instrumentation-aiohttp-server==0.63b0.dev", + "opentelemetry-instrumentation-aiokafka==0.63b0.dev", + "opentelemetry-instrumentation-aiopg==0.63b0.dev", + "opentelemetry-instrumentation-asgi==0.63b0.dev", + "opentelemetry-instrumentation-asyncclick==0.63b0.dev", + "opentelemetry-instrumentation-asyncio==0.63b0.dev", + "opentelemetry-instrumentation-asyncpg==0.63b0.dev", + "opentelemetry-instrumentation-aws-lambda==0.63b0.dev", + "opentelemetry-instrumentation-boto3sqs==0.63b0.dev", + "opentelemetry-instrumentation-botocore==0.63b0.dev", + "opentelemetry-instrumentation-cassandra==0.63b0.dev", + "opentelemetry-instrumentation-celery==0.63b0.dev", + "opentelemetry-instrumentation-click==0.63b0.dev", + "opentelemetry-instrumentation-confluent-kafka==0.63b0.dev", + "opentelemetry-instrumentation-dbapi==0.63b0.dev", + "opentelemetry-instrumentation-django==0.63b0.dev", + "opentelemetry-instrumentation-elasticsearch==0.63b0.dev", + "opentelemetry-instrumentation-falcon==0.63b0.dev", + "opentelemetry-instrumentation-fastapi==0.63b0.dev", + "opentelemetry-instrumentation-flask==0.63b0.dev", + "opentelemetry-instrumentation-grpc==0.63b0.dev", + "opentelemetry-instrumentation-httpx==0.63b0.dev", + "opentelemetry-instrumentation-jinja2==0.63b0.dev", + "opentelemetry-instrumentation-kafka-python==0.63b0.dev", + "opentelemetry-instrumentation-logging==0.63b0.dev", + "opentelemetry-instrumentation-mysql==0.63b0.dev", + "opentelemetry-instrumentation-mysqlclient==0.63b0.dev", + "opentelemetry-instrumentation-pika==0.63b0.dev", + "opentelemetry-instrumentation-psycopg==0.63b0.dev", + "opentelemetry-instrumentation-psycopg2==0.63b0.dev", + "opentelemetry-instrumentation-pymemcache==0.63b0.dev", + "opentelemetry-instrumentation-pymongo==0.63b0.dev", + "opentelemetry-instrumentation-pymssql==0.63b0.dev", + "opentelemetry-instrumentation-pymysql==0.63b0.dev", + "opentelemetry-instrumentation-pyramid==0.63b0.dev", + "opentelemetry-instrumentation-redis==0.63b0.dev", + "opentelemetry-instrumentation-remoulade==0.63b0.dev", + "opentelemetry-instrumentation-requests==0.63b0.dev", + "opentelemetry-instrumentation-sqlalchemy==0.63b0.dev", + "opentelemetry-instrumentation-sqlite3==0.63b0.dev", + "opentelemetry-instrumentation-starlette==0.63b0.dev", + "opentelemetry-instrumentation-system-metrics==0.63b0.dev", + "opentelemetry-instrumentation-threading==0.63b0.dev", + "opentelemetry-instrumentation-tornado==0.63b0.dev", + "opentelemetry-instrumentation-tortoiseorm==0.63b0.dev", + "opentelemetry-instrumentation-urllib==0.63b0.dev", + "opentelemetry-instrumentation-urllib3==0.63b0.dev", + "opentelemetry-instrumentation-wsgi==0.63b0.dev", ] [project.urls] diff --git a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py +++ b/opentelemetry-contrib-instrumentations/src/opentelemetry/contrib-instrumentations/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index d57eb6c31c3..538237ea031 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -28,13 +28,13 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.12", - "opentelemetry-instrumentation == 0.62b0.dev", + "opentelemetry-instrumentation == 0.63b0.dev", "opentelemetry-sdk ~= 1.13", ] [project.optional-dependencies] otlp = [ - "opentelemetry-exporter-otlp == 1.41.0.dev", + "opentelemetry-exporter-otlp == 1.42.0.dev", ] [project.entry-points.opentelemetry_configurator] diff --git a/opentelemetry-distro/src/opentelemetry/distro/version.py b/opentelemetry-distro/src/opentelemetry/distro/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/opentelemetry-distro/src/opentelemetry/distro/version.py +++ b/opentelemetry-distro/src/opentelemetry/distro/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index dd044ce2baa..00de032a445 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-api ~= 1.4", - "opentelemetry-semantic-conventions == 0.62b0.dev", + "opentelemetry-semantic-conventions == 0.63b0.dev", "wrapt >= 1.0.0, < 3.0.0", "packaging >= 18.0", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py index 0eb4c38733e..999181bd9f8 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py @@ -26,199 +26,199 @@ }, { "library": "aio_pika >= 7.2.0, < 10.0.0", - "instrumentation": "opentelemetry-instrumentation-aio-pika==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-aio-pika==0.63b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.63b0.dev", }, { "library": "aiohttp ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.63b0.dev", }, { "library": "aiokafka >= 0.8, < 1.0", - "instrumentation": "opentelemetry-instrumentation-aiokafka==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiokafka==0.63b0.dev", }, { "library": "aiopg >= 0.13.0, < 2.0.0", - "instrumentation": "opentelemetry-instrumentation-aiopg==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-aiopg==0.63b0.dev", }, { "library": "asgiref ~= 3.0", - "instrumentation": "opentelemetry-instrumentation-asgi==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-asgi==0.63b0.dev", }, { "library": "asyncclick ~= 8.0", - "instrumentation": "opentelemetry-instrumentation-asyncclick==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-asyncclick==0.63b0.dev", }, { "library": "asyncpg >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-asyncpg==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-asyncpg==0.63b0.dev", }, { "library": "boto3 ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.63b0.dev", }, { "library": "botocore ~= 1.0", - "instrumentation": "opentelemetry-instrumentation-botocore==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-botocore==0.63b0.dev", }, { "library": "aiobotocore ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-botocore==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-botocore==0.63b0.dev", }, { "library": "cassandra-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.63b0.dev", }, { "library": "scylla-driver ~= 3.25", - "instrumentation": "opentelemetry-instrumentation-cassandra==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-cassandra==0.63b0.dev", }, { "library": "celery >= 4.0, < 6.0", - "instrumentation": "opentelemetry-instrumentation-celery==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-celery==0.63b0.dev", }, { "library": "click >= 8.1.3, < 9.0.0", - "instrumentation": "opentelemetry-instrumentation-click==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-click==0.63b0.dev", }, { "library": "confluent-kafka >= 1.8.2, < 3.0.0", - "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.63b0.dev", }, { "library": "django >= 2.0", - "instrumentation": "opentelemetry-instrumentation-django==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-django==0.63b0.dev", }, { "library": "elasticsearch >= 6.0", - "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.63b0.dev", }, { "library": "falcon >= 1.4.1, < 5.0.0", - "instrumentation": "opentelemetry-instrumentation-falcon==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-falcon==0.63b0.dev", }, { "library": "fastapi ~= 0.92", - "instrumentation": "opentelemetry-instrumentation-fastapi==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-fastapi==0.63b0.dev", }, { "library": "flask >= 1.0", - "instrumentation": "opentelemetry-instrumentation-flask==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-flask==0.63b0.dev", }, { "library": "grpcio >= 1.42.0", - "instrumentation": "opentelemetry-instrumentation-grpc==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-grpc==0.63b0.dev", }, { "library": "httpx >= 0.18.0", - "instrumentation": "opentelemetry-instrumentation-httpx==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-httpx==0.63b0.dev", }, { "library": "jinja2 >= 2.7, < 4.0", - "instrumentation": "opentelemetry-instrumentation-jinja2==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-jinja2==0.63b0.dev", }, { "library": "kafka-python >= 2.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.63b0.dev", }, { "library": "kafka-python-ng >= 2.0, < 3.0", - "instrumentation": "opentelemetry-instrumentation-kafka-python==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-kafka-python==0.63b0.dev", }, { "library": "mysql-connector-python >= 8.0, < 10.0", - "instrumentation": "opentelemetry-instrumentation-mysql==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysql==0.63b0.dev", }, { "library": "mysqlclient < 3", - "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.63b0.dev", }, { "library": "pika >= 0.12.0", - "instrumentation": "opentelemetry-instrumentation-pika==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-pika==0.63b0.dev", }, { "library": "psycopg >= 3.1.0", - "instrumentation": "opentelemetry-instrumentation-psycopg==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg==0.63b0.dev", }, { "library": "psycopg2 >= 2.7.3.1", - "instrumentation": "opentelemetry-instrumentation-psycopg2==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg2==0.63b0.dev", }, { "library": "psycopg2-binary >= 2.7.3.1", - "instrumentation": "opentelemetry-instrumentation-psycopg2==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-psycopg2==0.63b0.dev", }, { "library": "pymemcache >= 1.3.5, < 5", - "instrumentation": "opentelemetry-instrumentation-pymemcache==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymemcache==0.63b0.dev", }, { "library": "pymongo >= 3.1, < 5.0", - "instrumentation": "opentelemetry-instrumentation-pymongo==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymongo==0.63b0.dev", }, { "library": "pymssql >= 2.1.5, < 3", - "instrumentation": "opentelemetry-instrumentation-pymssql==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymssql==0.63b0.dev", }, { "library": "PyMySQL < 2", - "instrumentation": "opentelemetry-instrumentation-pymysql==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-pymysql==0.63b0.dev", }, { "library": "pyramid >= 1.7", - "instrumentation": "opentelemetry-instrumentation-pyramid==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-pyramid==0.63b0.dev", }, { "library": "redis >= 2.6", - "instrumentation": "opentelemetry-instrumentation-redis==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-redis==0.63b0.dev", }, { "library": "remoulade >= 0.50", - "instrumentation": "opentelemetry-instrumentation-remoulade==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-remoulade==0.63b0.dev", }, { "library": "requests ~= 2.0", - "instrumentation": "opentelemetry-instrumentation-requests==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-requests==0.63b0.dev", }, { "library": "sqlalchemy >= 1.0.0, < 2.1.0", - "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.63b0.dev", }, { "library": "starlette >= 0.13", - "instrumentation": "opentelemetry-instrumentation-starlette==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-starlette==0.63b0.dev", }, { "library": "psutil >= 5", - "instrumentation": "opentelemetry-instrumentation-system-metrics==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-system-metrics==0.63b0.dev", }, { "library": "tornado >= 5.1.1", - "instrumentation": "opentelemetry-instrumentation-tornado==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-tornado==0.63b0.dev", }, { "library": "tortoise-orm >= 0.17.0", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.63b0.dev", }, { "library": "pydantic >= 1.10.2", - "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.63b0.dev", }, { "library": "urllib3 >= 1.0.0, < 3.0.0", - "instrumentation": "opentelemetry-instrumentation-urllib3==0.62b0.dev", + "instrumentation": "opentelemetry-instrumentation-urllib3==0.63b0.dev", }, ] default_instrumentations = [ - "opentelemetry-instrumentation-asyncio==0.62b0.dev", - "opentelemetry-instrumentation-dbapi==0.62b0.dev", - "opentelemetry-instrumentation-logging==0.62b0.dev", - "opentelemetry-instrumentation-sqlite3==0.62b0.dev", - "opentelemetry-instrumentation-threading==0.62b0.dev", - "opentelemetry-instrumentation-urllib==0.62b0.dev", - "opentelemetry-instrumentation-wsgi==0.62b0.dev", + "opentelemetry-instrumentation-asyncio==0.63b0.dev", + "opentelemetry-instrumentation-dbapi==0.63b0.dev", + "opentelemetry-instrumentation-logging==0.63b0.dev", + "opentelemetry-instrumentation-sqlite3==0.63b0.dev", + "opentelemetry-instrumentation-threading==0.63b0.dev", + "opentelemetry-instrumentation-urllib==0.63b0.dev", + "opentelemetry-instrumentation-wsgi==0.63b0.dev", ] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py +++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/resource/opentelemetry-resource-detector-containerid/src/opentelemetry/resource/detector/containerid/version.py b/resource/opentelemetry-resource-detector-containerid/src/opentelemetry/resource/detector/containerid/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/resource/opentelemetry-resource-detector-containerid/src/opentelemetry/resource/detector/containerid/version.py +++ b/resource/opentelemetry-resource-detector-containerid/src/opentelemetry/resource/detector/containerid/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py index ed89ddd1cc5..a07bc2663e4 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.62b0.dev" +__version__ = "0.63b0.dev" From 7f107df168b79af06326feef1cd3a38a25e726d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 07:59:48 +0000 Subject: [PATCH 61/78] build(deps): bump aiohttp from 3.13.3 to 3.13.4 (#4386) --- updated-dependencies: - dependency-name: aiohttp dependency-version: 3.13.4 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-requirements.txt b/docs-requirements.txt index 04c5e2eb62b..8f743798bc5 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -17,7 +17,7 @@ fsspec>=2025.9.0 # Required by instrumentation and exporter packages aio_pika~=7.2.0 -aiohttp~=3.0 +aiohttp~=3.13 aiokafka~=0.11.0 aiopg>=0.13.0,<1.3.0 asyncpg>=0.12.0 From 3a6895e8fba8e09a570e81ec7823087ab17696e3 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 13 Apr 2026 15:28:16 +0200 Subject: [PATCH 62/78] Revert "Build list of required jobs in generate-workflow (#4326)" (#4413) This reverts commit 22879d6b9fd252dcf5a77ec229e497105717d9b4. Now that we have just one job to check we don't need to build the list anymore. --- .github/workflows/generate_required_checks.py | 42 ------------------- .gitignore | 3 -- tox.ini | 1 - 3 files changed, 46 deletions(-) delete mode 100644 .github/workflows/generate_required_checks.py diff --git a/.github/workflows/generate_required_checks.py b/.github/workflows/generate_required_checks.py deleted file mode 100644 index 8e9185f76ec..00000000000 --- a/.github/workflows/generate_required_checks.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -This script builds a text file with the list of required checks based on -the tox environments. Similarly to the system we are using to build the -github workflows. -The output is in the format than can be cut-and-pasted into the python-contrib -terraform configuration in the admin repository. -""" - -from pathlib import Path - -from generate_workflows_lib import ( - get_lint_job_datas, - get_misc_job_datas, - get_test_job_datas, - get_tox_envs, -) - -tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini") - - -def get_gh_contexts_from_jobs(job_datas): - def get_job_name(job): - if isinstance(job, str): - return job - return job["ui_name"] - - return [ - f""" {{ context = "{get_job_name(job)}" }},\n""" - for job in job_datas - ] - - -jobs = sorted( - get_gh_contexts_from_jobs(get_lint_job_datas(get_tox_envs(tox_ini_path))) - + get_gh_contexts_from_jobs( - get_test_job_datas(get_tox_envs(tox_ini_path), ["ubuntu-latest"]) - ) - + get_gh_contexts_from_jobs(get_misc_job_datas(get_tox_envs(tox_ini_path))) -) -with open("opentelemetry-admin-jobs.txt", "w") as f: - for job in jobs: - f.write(job) diff --git a/.gitignore b/.gitignore index 09141b12eb4..1c32b4446a9 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,3 @@ target # Benchmark result files *-benchmark.json - -# opentelemetry-admin jobs -opentelemetry-admin-jobs.txt diff --git a/tox.ini b/tox.ini index 5b13ed9365a..8d8d86305b7 100644 --- a/tox.ini +++ b/tox.ini @@ -1124,7 +1124,6 @@ deps = commands = python {toxinidir}/.github/workflows/generate_workflows.py - python {toxinidir}/.github/workflows/generate_required_checks.py [testenv:shellcheck] From a912524656783e7b2912daf98f3fac3810f87a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:14:13 -0300 Subject: [PATCH 63/78] Drop Python 3.9 support (#4412) * Drop Python 3.9 support Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * generate-workflows Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fixes Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * remove extra reference to pypy310 Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * changelog Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix flask tests Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix google-genai tests Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix google-genai tests Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * remove unused _ensure_gzip_single_response Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .github/ISSUE_TEMPLATE/bug_report.yaml | 8 +- .github/workflows/core_contrib_test.yml | 1102 ++++--- .../generate_workflows_lib/pyproject.toml | 3 +- .../src/generate_workflows_lib/__init__.py | 6 +- .../core_contrib_test.yml.j2 | 4 +- .../package-prepare-patch-release.yml | 4 +- .github/workflows/package-prepare-release.yml | 8 +- .github/workflows/package-release.yml | 2 +- .github/workflows/prepare-patch-release.yml | 4 +- .github/workflows/prepare-release-branch.yml | 8 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2932 +++-------------- .pylintrc | 10 +- CHANGELOG.md | 9 +- _template/pyproject.toml | 3 +- dev-requirements.txt | 3 +- .../pyproject.toml | 3 +- .../example/Dockerfile | 2 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_async_wrappers.py | 6 +- .../pyproject.toml | 4 +- .../tests/generate_content/test_e2e.py | 51 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_response_wrappers.py | 6 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_instrumentation.py | 41 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_asyncio_anext.py | 5 - .../pyproject.toml | 3 +- .../tests/test_asyncpg_wrapper.py | 2 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_botocore_lambda.py | 2 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../test-requirements-0.txt | 1 + .../test-requirements-2.txt | 1 - .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../instrumentation/flask/__init__.py | 11 +- .../tests/test_flask_compatibility.py | 5 - .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../test-requirements.latest.txt | 21 +- .../test-requirements.oldest.txt | 14 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../opentelemetry-opamp-client/pyproject.toml | 3 +- .../test-requirements.latest.txt | 9 +- .../test-requirements.lowest.txt | 9 +- .../tests/opamp/test_e2e.py | 9 - .../pyproject.toml | 3 +- opentelemetry-distro/pyproject.toml | 3 +- opentelemetry-instrumentation/pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- pyproject.toml | 6 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- tox.ini | 171 +- util/opentelemetry-util-genai/pyproject.toml | 3 +- util/opentelemetry-util-http/pyproject.toml | 3 +- 107 files changed, 1266 insertions(+), 3431 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 5265ebb3f96..1695f77f84a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -8,8 +8,8 @@ body: value: | Thanks for taking the time to fill out this bug report! Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage and track down your bug as quickly as possible. - Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-python-contrib/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug) to see if your bug is already addressed. - + Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-python-contrib/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug) to see if your bug is already addressed. + - type: textarea id: environment attributes: @@ -18,9 +18,9 @@ body: Please describe any aspect of your environment relevant to the problem, including your Python version, [platform](https://docs.python.org/3/library/platform.html), version numbers of installed dependencies, information about your cloud hosting provider, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main. value: | OS: (e.g, Ubuntu) - Python version: (e.g., Python 3.9.10) + Python version: (e.g., Python 3.10.0) Package version: (e.g., 0.46.0) - + - type: textarea attributes: label: What happened? diff --git a/.github/workflows/core_contrib_test.yml b/.github/workflows/core_contrib_test.yml index 4653f3d360f..d9f90d57d89 100644 --- a/.github/workflows/core_contrib_test.yml +++ b/.github/workflows/core_contrib_test.yml @@ -27,7 +27,7 @@ env: jobs: - py39-test-instrumentation-openai-v2-oldest: + py310-test-instrumentation-openai-v2-oldest: name: instrumentation-openai-v2-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -45,19 +45,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-oldest -- -ra + run: tox -e py310-test-instrumentation-openai-v2-oldest -- -ra - py39-test-instrumentation-openai-v2-latest: + py310-test-instrumentation-openai-v2-latest: name: instrumentation-openai-v2-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -75,19 +75,79 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-latest -- -ra + run: tox -e py310-test-instrumentation-openai-v2-latest -- -ra - py39-test-instrumentation-vertexai-oldest: + py310-test-instrumentation-openai_agents-v2-oldest: + name: instrumentation-openai_agents-v2-oldest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-openai_agents-v2-oldest -- -ra + + py310-test-instrumentation-openai_agents-v2-latest: + name: instrumentation-openai_agents-v2-latest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-openai_agents-v2-latest -- -ra + + py310-test-instrumentation-vertexai-oldest: name: instrumentation-vertexai-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -105,19 +165,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-oldest -- -ra + run: tox -e py310-test-instrumentation-vertexai-oldest -- -ra - py39-test-instrumentation-vertexai-latest: + py310-test-instrumentation-vertexai-latest: name: instrumentation-vertexai-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -135,19 +195,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-latest -- -ra + run: tox -e py310-test-instrumentation-vertexai-latest -- -ra - py39-test-instrumentation-google-genai-oldest: + py310-test-instrumentation-google-genai-oldest: name: instrumentation-google-genai-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -165,19 +225,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-oldest -- -ra + run: tox -e py310-test-instrumentation-google-genai-oldest -- -ra - py39-test-instrumentation-google-genai-latest: + py310-test-instrumentation-google-genai-latest: name: instrumentation-google-genai-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -195,19 +255,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-latest -- -ra + run: tox -e py310-test-instrumentation-google-genai-latest -- -ra - py39-test-instrumentation-anthropic-oldest: + py310-test-instrumentation-anthropic-oldest: name: instrumentation-anthropic-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -225,19 +285,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-oldest -- -ra + run: tox -e py310-test-instrumentation-anthropic-oldest -- -ra - py39-test-instrumentation-anthropic-latest: + py310-test-instrumentation-anthropic-latest: name: instrumentation-anthropic-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -255,19 +315,79 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-latest -- -ra + run: tox -e py310-test-instrumentation-anthropic-latest -- -ra + + py310-test-instrumentation-claude-agent-sdk-oldest: + name: instrumentation-claude-agent-sdk-oldest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python - py39-test-resource-detector-containerid: + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-claude-agent-sdk-oldest -- -ra + + py310-test-instrumentation-claude-agent-sdk-latest: + name: instrumentation-claude-agent-sdk-latest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-claude-agent-sdk-latest -- -ra + + py310-test-resource-detector-containerid: name: resource-detector-containerid runs-on: ubuntu-latest timeout-minutes: 30 @@ -285,19 +405,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-resource-detector-containerid -- -ra + run: tox -e py310-test-resource-detector-containerid -- -ra - py39-test-resource-detector-azure-0: + py310-test-resource-detector-azure-0: name: resource-detector-azure-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -315,19 +435,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-resource-detector-azure-0 -- -ra + run: tox -e py310-test-resource-detector-azure-0 -- -ra - py39-test-resource-detector-azure-1: + py310-test-resource-detector-azure-1: name: resource-detector-azure-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -345,19 +465,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-resource-detector-azure-1 -- -ra + run: tox -e py310-test-resource-detector-azure-1 -- -ra - py39-test-sdk-extension-aws-0: + py310-test-sdk-extension-aws-0: name: sdk-extension-aws-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -375,19 +495,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-sdk-extension-aws-0 -- -ra + run: tox -e py310-test-sdk-extension-aws-0 -- -ra - py39-test-sdk-extension-aws-1: + py310-test-sdk-extension-aws-1: name: sdk-extension-aws-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -405,19 +525,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-sdk-extension-aws-1 -- -ra + run: tox -e py310-test-sdk-extension-aws-1 -- -ra - py39-test-distro: + py310-test-distro: name: distro runs-on: ubuntu-latest timeout-minutes: 30 @@ -435,19 +555,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-distro -- -ra + run: tox -e py310-test-distro -- -ra - py39-test-opentelemetry-instrumentation-wrapt1: + py310-test-opentelemetry-instrumentation-wrapt1: name: opentelemetry-instrumentation-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -465,19 +585,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt1 -- -ra + run: tox -e py310-test-opentelemetry-instrumentation-wrapt1 -- -ra - py39-test-opentelemetry-instrumentation-wrapt2: + py310-test-opentelemetry-instrumentation-wrapt2: name: opentelemetry-instrumentation-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -495,19 +615,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt2 -- -ra + run: tox -e py310-test-opentelemetry-instrumentation-wrapt2 -- -ra - py39-test-instrumentation-aiohttp-client: + py310-test-instrumentation-aiohttp-client: name: instrumentation-aiohttp-client runs-on: ubuntu-latest timeout-minutes: 30 @@ -525,19 +645,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-client -- -ra + run: tox -e py310-test-instrumentation-aiohttp-client -- -ra - py39-test-instrumentation-aiohttp-server: + py310-test-instrumentation-aiohttp-server: name: instrumentation-aiohttp-server runs-on: ubuntu-latest timeout-minutes: 30 @@ -555,19 +675,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-server -- -ra + run: tox -e py310-test-instrumentation-aiohttp-server -- -ra - py39-test-instrumentation-aiopg-wrapt1: + py310-test-instrumentation-aiopg-wrapt1: name: instrumentation-aiopg-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -585,19 +705,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-aiopg-wrapt1 -- -ra - py39-test-instrumentation-aiopg-wrapt2: + py310-test-instrumentation-aiopg-wrapt2: name: instrumentation-aiopg-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -615,19 +735,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-aiopg-wrapt2 -- -ra - py39-test-instrumentation-aws-lambda: + py310-test-instrumentation-aws-lambda: name: instrumentation-aws-lambda runs-on: ubuntu-latest timeout-minutes: 30 @@ -645,19 +765,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aws-lambda -- -ra + run: tox -e py310-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-botocore-0-wrapt1: + py310-test-instrumentation-botocore-0-wrapt1: name: instrumentation-botocore-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -675,19 +795,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-botocore-0-wrapt1 -- -ra - py39-test-instrumentation-botocore-0-wrapt2: + py310-test-instrumentation-botocore-0-wrapt2: name: instrumentation-botocore-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -705,19 +825,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-botocore-0-wrapt2 -- -ra - py39-test-instrumentation-botocore-1-wrapt1: + py310-test-instrumentation-botocore-1-wrapt1: name: instrumentation-botocore-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -735,19 +855,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-botocore-1-wrapt1 -- -ra - py39-test-instrumentation-botocore-1-wrapt2: + py310-test-instrumentation-botocore-1-wrapt2: name: instrumentation-botocore-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -765,19 +885,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-botocore-1-wrapt2 -- -ra - py39-test-instrumentation-botocore-2: + py310-test-instrumentation-botocore-2: name: instrumentation-botocore-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -795,19 +915,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-2 -- -ra + run: tox -e py310-test-instrumentation-botocore-2 -- -ra - py39-test-instrumentation-botocore-3: + py310-test-instrumentation-botocore-3: name: instrumentation-botocore-3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -825,19 +945,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-3 -- -ra + run: tox -e py310-test-instrumentation-botocore-3 -- -ra - py39-test-instrumentation-boto3sqs: + py310-test-instrumentation-boto3sqs: name: instrumentation-boto3sqs runs-on: ubuntu-latest timeout-minutes: 30 @@ -855,19 +975,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-boto3sqs -- -ra + run: tox -e py310-test-instrumentation-boto3sqs -- -ra - py39-test-instrumentation-django-0: + py310-test-instrumentation-django-0: name: instrumentation-django-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -885,19 +1005,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-0 -- -ra + run: tox -e py310-test-instrumentation-django-0 -- -ra - py39-test-instrumentation-django-1: + py310-test-instrumentation-django-1: name: instrumentation-django-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -915,19 +1035,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-1 -- -ra + run: tox -e py310-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-django-2: + py310-test-instrumentation-django-2: name: instrumentation-django-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -945,19 +1065,49 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-django-2 -- -ra + + py310-test-instrumentation-django-3: + name: instrumentation-django-3 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-2 -- -ra + run: tox -e py310-test-instrumentation-django-3 -- -ra - py39-test-instrumentation-dbapi-wrapt1: + py310-test-instrumentation-dbapi-wrapt1: name: instrumentation-dbapi-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -975,19 +1125,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-dbapi-wrapt1 -- -ra - py39-test-instrumentation-dbapi-wrapt2: + py310-test-instrumentation-dbapi-wrapt2: name: instrumentation-dbapi-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1005,19 +1155,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-dbapi-wrapt2 -- -ra - py39-test-instrumentation-asyncclick: + py310-test-instrumentation-asyncclick: name: instrumentation-asyncclick runs-on: ubuntu-latest timeout-minutes: 30 @@ -1035,19 +1185,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncclick -- -ra + run: tox -e py310-test-instrumentation-asyncclick -- -ra - py39-test-instrumentation-click: + py310-test-instrumentation-click: name: instrumentation-click runs-on: ubuntu-latest timeout-minutes: 30 @@ -1065,19 +1215,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-click -- -ra + run: tox -e py310-test-instrumentation-click -- -ra - py39-test-instrumentation-elasticsearch-0: + py310-test-instrumentation-elasticsearch-0: name: instrumentation-elasticsearch-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1095,19 +1245,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra - py39-test-instrumentation-elasticsearch-1: + py310-test-instrumentation-elasticsearch-1: name: instrumentation-elasticsearch-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1125,19 +1275,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra - py39-test-instrumentation-elasticsearch-2: + py310-test-instrumentation-elasticsearch-2: name: instrumentation-elasticsearch-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1155,20 +1305,20 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra - py39-test-instrumentation-falcon-0: - name: instrumentation-falcon-0 + py310-test-instrumentation-falcon-1: + name: instrumentation-falcon-1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1185,20 +1335,20 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra + run: tox -e py310-test-instrumentation-falcon-1 -- -ra - py39-test-instrumentation-falcon-1: - name: instrumentation-falcon-1 + py310-test-instrumentation-falcon-2: + name: instrumentation-falcon-2 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1215,20 +1365,20 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra + run: tox -e py310-test-instrumentation-falcon-2 -- -ra - py39-test-instrumentation-falcon-2: - name: instrumentation-falcon-2 + py310-test-instrumentation-falcon-3: + name: instrumentation-falcon-3 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1245,20 +1395,20 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-2 -- -ra + run: tox -e py310-test-instrumentation-falcon-3 -- -ra - py39-test-instrumentation-falcon-3: - name: instrumentation-falcon-3 + py310-test-instrumentation-falcon-4: + name: instrumentation-falcon-4 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1275,19 +1425,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-3 -- -ra + run: tox -e py310-test-instrumentation-falcon-4 -- -ra - py39-test-instrumentation-fastapi: + py310-test-instrumentation-fastapi: name: instrumentation-fastapi runs-on: ubuntu-latest timeout-minutes: 30 @@ -1305,19 +1455,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-fastapi -- -ra + run: tox -e py310-test-instrumentation-fastapi -- -ra - py39-test-instrumentation-flask-0: + py310-test-instrumentation-flask-0: name: instrumentation-flask-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1335,19 +1485,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-0 -- -ra + run: tox -e py310-test-instrumentation-flask-0 -- -ra - py39-test-instrumentation-flask-1: + py310-test-instrumentation-flask-1: name: instrumentation-flask-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1365,19 +1515,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-1 -- -ra + run: tox -e py310-test-instrumentation-flask-1 -- -ra - py39-test-instrumentation-flask-2: + py310-test-instrumentation-flask-2: name: instrumentation-flask-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1395,19 +1545,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-2 -- -ra + run: tox -e py310-test-instrumentation-flask-2 -- -ra - py39-test-instrumentation-flask-3: + py310-test-instrumentation-flask-3: name: instrumentation-flask-3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1425,19 +1575,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-3 -- -ra + run: tox -e py310-test-instrumentation-flask-3 -- -ra - py39-test-instrumentation-urllib: + py310-test-instrumentation-urllib: name: instrumentation-urllib runs-on: ubuntu-latest timeout-minutes: 30 @@ -1455,19 +1605,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib -- -ra + run: tox -e py310-test-instrumentation-urllib -- -ra - py39-test-instrumentation-urllib3-0: + py310-test-instrumentation-urllib3-0: name: instrumentation-urllib3-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1485,19 +1635,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-urllib3-1: + py310-test-instrumentation-urllib3-1: name: instrumentation-urllib3-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1515,19 +1665,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - py39-test-instrumentation-requests: + py310-test-instrumentation-requests: name: instrumentation-requests runs-on: ubuntu-latest timeout-minutes: 30 @@ -1545,19 +1695,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-requests -- -ra + run: tox -e py310-test-instrumentation-requests -- -ra - py39-test-instrumentation-starlette-oldest: + py310-test-instrumentation-starlette-oldest: name: instrumentation-starlette-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -1575,19 +1725,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-starlette-oldest -- -ra + run: tox -e py310-test-instrumentation-starlette-oldest -- -ra - py39-test-instrumentation-starlette-latest: + py310-test-instrumentation-starlette-latest: name: instrumentation-starlette-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -1605,19 +1755,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-starlette-latest -- -ra + run: tox -e py310-test-instrumentation-starlette-latest -- -ra - py39-test-instrumentation-jinja2: + py310-test-instrumentation-jinja2: name: instrumentation-jinja2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1635,19 +1785,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-jinja2 -- -ra + run: tox -e py310-test-instrumentation-jinja2 -- -ra - py39-test-instrumentation-logging: + py310-test-instrumentation-logging: name: instrumentation-logging runs-on: ubuntu-latest timeout-minutes: 30 @@ -1665,19 +1815,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-logging -- -ra + run: tox -e py310-test-instrumentation-logging -- -ra - py39-test-exporter-richconsole: + py310-test-exporter-richconsole: name: exporter-richconsole runs-on: ubuntu-latest timeout-minutes: 30 @@ -1695,19 +1845,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-richconsole -- -ra + run: tox -e py310-test-exporter-richconsole -- -ra - py39-test-exporter-prometheus-remote-write: + py310-test-exporter-prometheus-remote-write: name: exporter-prometheus-remote-write runs-on: ubuntu-latest timeout-minutes: 30 @@ -1725,19 +1875,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-prometheus-remote-write -- -ra + run: tox -e py310-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-mysql-0: + py310-test-instrumentation-mysql-0: name: instrumentation-mysql-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1755,19 +1905,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysql-0 -- -ra + run: tox -e py310-test-instrumentation-mysql-0 -- -ra - py39-test-instrumentation-mysql-1: + py310-test-instrumentation-mysql-1: name: instrumentation-mysql-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1785,19 +1935,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra + run: tox -e py310-test-instrumentation-mysql-1 -- -ra - py39-test-instrumentation-mysqlclient: + py310-test-instrumentation-mysqlclient: name: instrumentation-mysqlclient runs-on: ubuntu-latest timeout-minutes: 30 @@ -1815,19 +1965,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra + run: tox -e py310-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-psycopg2: + py310-test-instrumentation-psycopg2: name: instrumentation-psycopg2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1845,19 +1995,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra + run: tox -e py310-test-instrumentation-psycopg2 -- -ra - py39-test-instrumentation-psycopg2-binary: + py310-test-instrumentation-psycopg2-binary: name: instrumentation-psycopg2-binary runs-on: ubuntu-latest timeout-minutes: 30 @@ -1875,19 +2025,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra + run: tox -e py310-test-instrumentation-psycopg2-binary -- -ra - py39-test-instrumentation-psycopg: + py310-test-instrumentation-psycopg: name: instrumentation-psycopg runs-on: ubuntu-latest timeout-minutes: 30 @@ -1905,19 +2055,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra + run: tox -e py310-test-instrumentation-psycopg -- -ra - py39-test-instrumentation-pymemcache-0: + py310-test-instrumentation-pymemcache-0: name: instrumentation-pymemcache-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1935,19 +2085,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - py39-test-instrumentation-pymemcache-1: + py310-test-instrumentation-pymemcache-1: name: instrumentation-pymemcache-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1965,19 +2115,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - py39-test-instrumentation-pymemcache-2: + py310-test-instrumentation-pymemcache-2: name: instrumentation-pymemcache-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1995,19 +2145,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra - py39-test-instrumentation-pymemcache-3: + py310-test-instrumentation-pymemcache-3: name: instrumentation-pymemcache-3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2025,19 +2175,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra - py39-test-instrumentation-pymemcache-4: + py310-test-instrumentation-pymemcache-4: name: instrumentation-pymemcache-4 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2055,19 +2205,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra - py39-test-instrumentation-pymongo: + py310-test-instrumentation-pymongo: name: instrumentation-pymongo runs-on: ubuntu-latest timeout-minutes: 30 @@ -2085,19 +2235,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymongo -- -ra + run: tox -e py310-test-instrumentation-pymongo -- -ra - py39-test-instrumentation-pymysql: + py310-test-instrumentation-pymysql: name: instrumentation-pymysql runs-on: ubuntu-latest timeout-minutes: 30 @@ -2115,19 +2265,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymysql -- -ra + run: tox -e py310-test-instrumentation-pymysql -- -ra - py39-test-instrumentation-pymssql: + py310-test-instrumentation-pymssql: name: instrumentation-pymssql runs-on: ubuntu-latest timeout-minutes: 30 @@ -2145,19 +2295,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymssql -- -ra + run: tox -e py310-test-instrumentation-pymssql -- -ra - py39-test-instrumentation-pyramid: + py310-test-instrumentation-pyramid: name: instrumentation-pyramid runs-on: ubuntu-latest timeout-minutes: 30 @@ -2175,19 +2325,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pyramid -- -ra + run: tox -e py310-test-instrumentation-pyramid -- -ra - py39-test-instrumentation-asgi: + py310-test-instrumentation-asgi: name: instrumentation-asgi runs-on: ubuntu-latest timeout-minutes: 30 @@ -2205,19 +2355,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asgi -- -ra + run: tox -e py310-test-instrumentation-asgi -- -ra - py39-test-instrumentation-asyncpg-wrapt1: + py310-test-instrumentation-asyncpg-wrapt1: name: instrumentation-asyncpg-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2235,19 +2385,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-asyncpg-wrapt1 -- -ra - py39-test-instrumentation-asyncpg-wrapt2: + py310-test-instrumentation-asyncpg-wrapt2: name: instrumentation-asyncpg-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2265,19 +2415,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-asyncpg-wrapt2 -- -ra - py39-test-instrumentation-sqlite3: + py310-test-instrumentation-sqlite3: name: instrumentation-sqlite3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2295,19 +2445,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlite3 -- -ra + run: tox -e py310-test-instrumentation-sqlite3 -- -ra - py39-test-instrumentation-wsgi: + py310-test-instrumentation-wsgi: name: instrumentation-wsgi runs-on: ubuntu-latest timeout-minutes: 30 @@ -2325,19 +2475,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra + run: tox -e py310-test-instrumentation-wsgi -- -ra - py39-test-instrumentation-grpc-0-wrapt1: + py310-test-instrumentation-grpc-0-wrapt1: name: instrumentation-grpc-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2355,19 +2505,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra - py39-test-instrumentation-grpc-0-wrapt2: + py310-test-instrumentation-grpc-0-wrapt2: name: instrumentation-grpc-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2385,19 +2535,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra - py39-test-instrumentation-grpc-1-wrapt1: + py310-test-instrumentation-grpc-1-wrapt1: name: instrumentation-grpc-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2415,19 +2565,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra - py39-test-instrumentation-grpc-1-wrapt2: + py310-test-instrumentation-grpc-1-wrapt2: name: instrumentation-grpc-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2445,19 +2595,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra - py39-test-instrumentation-sqlalchemy-1: + py310-test-instrumentation-sqlalchemy-1: name: instrumentation-sqlalchemy-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2475,19 +2625,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra - py39-test-instrumentation-sqlalchemy-2: + py310-test-instrumentation-sqlalchemy-2: name: instrumentation-sqlalchemy-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2505,19 +2655,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra - py39-test-instrumentation-redis: + py310-test-instrumentation-redis: name: instrumentation-redis runs-on: ubuntu-latest timeout-minutes: 30 @@ -2535,19 +2685,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-redis -- -ra + run: tox -e py310-test-instrumentation-redis -- -ra - py39-test-instrumentation-remoulade: + py310-test-instrumentation-remoulade: name: instrumentation-remoulade runs-on: ubuntu-latest timeout-minutes: 30 @@ -2565,19 +2715,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-remoulade -- -ra + run: tox -e py310-test-instrumentation-remoulade -- -ra - py39-test-instrumentation-celery: + py310-test-instrumentation-celery: name: instrumentation-celery runs-on: ubuntu-latest timeout-minutes: 30 @@ -2595,19 +2745,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-celery -- -ra + run: tox -e py310-test-instrumentation-celery -- -ra - py39-test-instrumentation-system-metrics: + py310-test-instrumentation-system-metrics: name: instrumentation-system-metrics runs-on: ubuntu-latest timeout-minutes: 30 @@ -2625,19 +2775,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-system-metrics -- -ra + run: tox -e py310-test-instrumentation-system-metrics -- -ra - py39-test-instrumentation-threading: + py310-test-instrumentation-threading: name: instrumentation-threading runs-on: ubuntu-latest timeout-minutes: 30 @@ -2655,19 +2805,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-threading -- -ra + run: tox -e py310-test-instrumentation-threading -- -ra - py39-test-instrumentation-tornado: + py310-test-instrumentation-tornado: name: instrumentation-tornado runs-on: ubuntu-latest timeout-minutes: 30 @@ -2685,19 +2835,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-tornado -- -ra + run: tox -e py310-test-instrumentation-tornado -- -ra - py39-test-instrumentation-tortoiseorm: + py310-test-instrumentation-tortoiseorm: name: instrumentation-tortoiseorm runs-on: ubuntu-latest timeout-minutes: 30 @@ -2715,19 +2865,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-tortoiseorm -- -ra + run: tox -e py310-test-instrumentation-tortoiseorm -- -ra - py39-test-instrumentation-httpx-0-wrapt1: + py310-test-instrumentation-httpx-0-wrapt1: name: instrumentation-httpx-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2745,19 +2895,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-httpx-0-wrapt1 -- -ra - py39-test-instrumentation-httpx-0-wrapt2: + py310-test-instrumentation-httpx-0-wrapt2: name: instrumentation-httpx-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2775,19 +2925,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-httpx-0-wrapt2 -- -ra - py39-test-instrumentation-httpx-1-wrapt1: + py310-test-instrumentation-httpx-1-wrapt1: name: instrumentation-httpx-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2805,19 +2955,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-httpx-1-wrapt1 -- -ra - py39-test-instrumentation-httpx-1-wrapt2: + py310-test-instrumentation-httpx-1-wrapt2: name: instrumentation-httpx-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2835,19 +2985,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-httpx-1-wrapt2 -- -ra - py39-test-util-http: + py310-test-util-http: name: util-http runs-on: ubuntu-latest timeout-minutes: 30 @@ -2865,19 +3015,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-util-http -- -ra + run: tox -e py310-test-util-http -- -ra - py39-test-exporter-credential-provider-gcp: + py310-test-exporter-credential-provider-gcp: name: exporter-credential-provider-gcp runs-on: ubuntu-latest timeout-minutes: 30 @@ -2895,19 +3045,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-credential-provider-gcp -- -ra + run: tox -e py310-test-exporter-credential-provider-gcp -- -ra - py39-test-util-genai: + py310-test-util-genai: name: util-genai runs-on: ubuntu-latest timeout-minutes: 30 @@ -2925,19 +3075,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-util-genai -- -ra + run: tox -e py310-test-util-genai -- -ra - py39-test-propagator-aws-xray-0: + py310-test-propagator-aws-xray-0: name: propagator-aws-xray-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2955,19 +3105,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-aws-xray-0 -- -ra + run: tox -e py310-test-propagator-aws-xray-0 -- -ra - py39-test-propagator-aws-xray-1: + py310-test-propagator-aws-xray-1: name: propagator-aws-xray-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2985,19 +3135,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-aws-xray-1 -- -ra + run: tox -e py310-test-propagator-aws-xray-1 -- -ra - py39-test-propagator-ot-trace: + py310-test-propagator-ot-trace: name: propagator-ot-trace runs-on: ubuntu-latest timeout-minutes: 30 @@ -3015,19 +3165,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-ot-trace -- -ra + run: tox -e py310-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-0-wrapt1: + py310-test-instrumentation-sio-pika-0-wrapt1: name: instrumentation-sio-pika-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3045,19 +3195,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-0-wrapt1 -- -ra - py39-test-instrumentation-sio-pika-0-wrapt2: + py310-test-instrumentation-sio-pika-0-wrapt2: name: instrumentation-sio-pika-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3075,19 +3225,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-0-wrapt2 -- -ra - py39-test-instrumentation-sio-pika-1-wrapt1: + py310-test-instrumentation-sio-pika-1-wrapt1: name: instrumentation-sio-pika-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3105,19 +3255,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-1-wrapt1 -- -ra - py39-test-instrumentation-sio-pika-1-wrapt2: + py310-test-instrumentation-sio-pika-1-wrapt2: name: instrumentation-sio-pika-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3135,19 +3285,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-1-wrapt2 -- -ra - py39-test-instrumentation-aio-pika-0: + py310-test-instrumentation-aio-pika-0: name: instrumentation-aio-pika-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3165,19 +3315,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra - py39-test-instrumentation-aio-pika-1: + py310-test-instrumentation-aio-pika-1: name: instrumentation-aio-pika-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3195,19 +3345,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra - py39-test-instrumentation-aio-pika-2: + py310-test-instrumentation-aio-pika-2: name: instrumentation-aio-pika-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3225,19 +3375,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra - py39-test-instrumentation-aio-pika-3: + py310-test-instrumentation-aio-pika-3: name: instrumentation-aio-pika-3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3255,19 +3405,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra - py39-test-instrumentation-aiokafka: + py310-test-instrumentation-aiokafka: name: instrumentation-aiokafka runs-on: ubuntu-latest timeout-minutes: 30 @@ -3285,19 +3435,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiokafka -- -ra + run: tox -e py310-test-instrumentation-aiokafka -- -ra - py39-test-instrumentation-kafka-python: + py310-test-instrumentation-kafka-python: name: instrumentation-kafka-python runs-on: ubuntu-latest timeout-minutes: 30 @@ -3315,19 +3465,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-kafka-python -- -ra + run: tox -e py310-test-instrumentation-kafka-python -- -ra - py39-test-instrumentation-kafka-pythonng: + py310-test-instrumentation-kafka-pythonng: name: instrumentation-kafka-pythonng runs-on: ubuntu-latest timeout-minutes: 30 @@ -3345,19 +3495,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra - py39-test-instrumentation-confluent-kafka: + py310-test-instrumentation-confluent-kafka: name: instrumentation-confluent-kafka runs-on: ubuntu-latest timeout-minutes: 30 @@ -3375,19 +3525,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-confluent-kafka -- -ra + run: tox -e py310-test-instrumentation-confluent-kafka -- -ra - py39-test-instrumentation-asyncio: + py310-test-instrumentation-asyncio: name: instrumentation-asyncio runs-on: ubuntu-latest timeout-minutes: 30 @@ -3405,19 +3555,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncio -- -ra + run: tox -e py310-test-instrumentation-asyncio -- -ra - py39-test-instrumentation-cassandra-driver: + py310-test-instrumentation-cassandra-driver: name: instrumentation-cassandra-driver runs-on: ubuntu-latest timeout-minutes: 30 @@ -3435,19 +3585,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-driver -- -ra + run: tox -e py310-test-instrumentation-cassandra-driver -- -ra - py39-test-instrumentation-cassandra-scylla: + py310-test-instrumentation-cassandra-scylla: name: instrumentation-cassandra-scylla runs-on: ubuntu-latest timeout-minutes: 30 @@ -3465,19 +3615,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-scylla -- -ra + run: tox -e py310-test-instrumentation-cassandra-scylla -- -ra - py39-test-processor-baggage: + py310-test-processor-baggage: name: processor-baggage runs-on: ubuntu-latest timeout-minutes: 30 @@ -3495,19 +3645,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra + run: tox -e py310-test-processor-baggage -- -ra - py39-test-opamp-client-latest: + py310-test-opamp-client-latest: name: opamp-client-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -3525,19 +3675,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opamp-client-latest -- -ra + run: tox -e py310-test-opamp-client-latest -- -ra - py39-test-opamp-client-lowest: + py310-test-opamp-client-lowest: name: opamp-client-lowest runs-on: ubuntu-latest timeout-minutes: 30 @@ -3555,14 +3705,14 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opamp-client-lowest -- -ra + run: tox -e py310-test-opamp-client-lowest -- -ra diff --git a/.github/workflows/generate_workflows_lib/pyproject.toml b/.github/workflows/generate_workflows_lib/pyproject.toml index 04106efc0f8..16bba5576c7 100644 --- a/.github/workflows/generate_workflows_lib/pyproject.toml +++ b/.github/workflows/generate_workflows_lib/pyproject.toml @@ -7,7 +7,7 @@ name = "generate-workflows-lib" dynamic = ["version"] description = "A library to generate workflows" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -17,7 +17,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py index a2e628a09ec..10f4ad921f8 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -14,7 +14,7 @@ ) _tox_lint_env_regex = re_compile(r"lint-(?P[-\w]+)") _tox_contrib_env_regex = re_compile( - r"py39-test-(?P[-\w]+\w)-?(?P\d+)?" + r"py310-test-(?P[-\w]+\w)-?(?P\d+)?" ) @@ -47,9 +47,7 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: os_alias = {"ubuntu-latest": "Ubuntu", "windows-latest": "Windows"} python_version_alias = { - "pypy3": "pypy-3.9", - "pypy310": "pypy-3.10", - "py39": "3.9", + "pypy3": "pypy-3.10", "py310": "3.10", "py311": "3.11", "py312": "3.12", diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 index 5fce8e1cfe2..46090ed333f 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 @@ -46,10 +46,10 @@ jobs: ref: ${% raw %}{{ env.CORE_REPO_SHA }}{% endraw %} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox diff --git a/.github/workflows/package-prepare-patch-release.yml b/.github/workflows/package-prepare-patch-release.yml index 917a579cfa4..5ad56159782 100644 --- a/.github/workflows/package-prepare-patch-release.yml +++ b/.github/workflows/package-prepare-patch-release.yml @@ -97,10 +97,10 @@ jobs: # replace the version in the version file (1.2.3 -> 1.2.4) sed -i -E "s/__version__\s*=\s*\"${VERSION}\"/__version__ = \"${NEXT_VERSION}\"/g" $VERSION_FILE - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox diff --git a/.github/workflows/package-prepare-release.yml b/.github/workflows/package-prepare-release.yml index 56b80728757..f9819d3668c 100644 --- a/.github/workflows/package-prepare-release.yml +++ b/.github/workflows/package-prepare-release.yml @@ -125,10 +125,10 @@ jobs: # replace the version in the version file (1.2.3dev -> 1.2.3) sed -i -E "s/__version__\s*=\s*\"${VERSION}\.dev\"/__version__ = \"${VERSION}\"/g" $VERSION_FILE - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox @@ -185,10 +185,10 @@ jobs: # replace the version in the version file (1.2.3dev -> 1.3.3.dev) sed -i -E "s/__version__\s*=\s*\"${VERSION}\.dev\"/__version__ = \"${NEXT_VERSION}.dev\"/g" $VERSION_FILE - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml index 7eb4b09d03d..3ab6341b551 100644 --- a/.github/workflows/package-release.yml +++ b/.github/workflows/package-release.yml @@ -88,7 +88,7 @@ jobs: # next few steps publish to pypi - uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.10' - name: Build wheels run: ./scripts/build_a_package.sh diff --git a/.github/workflows/prepare-patch-release.yml b/.github/workflows/prepare-patch-release.yml index 577fc86ba4f..b2ebdf41f1d 100644 --- a/.github/workflows/prepare-patch-release.yml +++ b/.github/workflows/prepare-patch-release.yml @@ -59,10 +59,10 @@ jobs: - name: Update version run: .github/scripts/update-version-patch.sh $STABLE_VERSION $UNSTABLE_VERSION $STABLE_VERSION_PREV $UNSTABLE_VERSION_PREV - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox diff --git a/.github/workflows/prepare-release-branch.yml b/.github/workflows/prepare-release-branch.yml index 1017a49a703..6804d112a6d 100644 --- a/.github/workflows/prepare-release-branch.yml +++ b/.github/workflows/prepare-release-branch.yml @@ -82,10 +82,10 @@ jobs: - name: Update version run: .github/scripts/update-version.sh $STABLE_VERSION $UNSTABLE_VERSION - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox @@ -184,10 +184,10 @@ jobs: - name: Update version run: .github/scripts/update-version.sh $STABLE_NEXT_VERSION $UNSTABLE_NEXT_VERSION - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e8fbb0dd36b..d7190f687f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -71,7 +71,7 @@ jobs: # next few steps publish to pypi - uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.10' - name: Build wheels run: ./scripts/build.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8aba00e1c21..9c694007ea7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,44 +24,6 @@ env: jobs: - py39-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-oldest -- -ra - - py39-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-latest -- -ra - py310-test-instrumentation-openai-v2-oldest_ubuntu-latest: name: instrumentation-openai-v2-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -272,17 +234,17 @@ jobs: run: tox -e py313-test-instrumentation-openai-v2-pydantic1 -- -ra pypy3-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest pypy-3.9 Ubuntu + name: instrumentation-openai-v2-oldest pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -291,17 +253,17 @@ jobs: run: tox -e pypy3-test-instrumentation-openai-v2-oldest -- -ra pypy3-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest pypy-3.9 Ubuntu + name: instrumentation-openai-v2-latest pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -499,44 +461,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-openai_agents-v2-latest -- -ra - py39-test-instrumentation-vertexai-oldest_ubuntu-latest: - name: instrumentation-vertexai-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-oldest -- -ra - - py39-test-instrumentation-vertexai-latest_ubuntu-latest: - name: instrumentation-vertexai-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-latest -- -ra - py310-test-instrumentation-vertexai-oldest_ubuntu-latest: name: instrumentation-vertexai-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -727,44 +651,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-vertexai-latest -- -ra - py39-test-instrumentation-google-genai-oldest_ubuntu-latest: - name: instrumentation-google-genai-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-oldest -- -ra - - py39-test-instrumentation-google-genai-latest_ubuntu-latest: - name: instrumentation-google-genai-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-latest -- -ra - py310-test-instrumentation-google-genai-oldest_ubuntu-latest: name: instrumentation-google-genai-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -955,44 +841,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-google-genai-latest -- -ra - py39-test-instrumentation-anthropic-oldest_ubuntu-latest: - name: instrumentation-anthropic-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-oldest -- -ra - - py39-test-instrumentation-anthropic-latest_ubuntu-latest: - name: instrumentation-anthropic-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-latest -- -ra - py310-test-instrumentation-anthropic-oldest_ubuntu-latest: name: instrumentation-anthropic-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -1335,25 +1183,6 @@ jobs: - name: Run tests run: tox -e py313-test-instrumentation-claude-agent-sdk-latest -- -ra - py39-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-containerid -- -ra - py310-test-resource-detector-containerid_ubuntu-latest: name: resource-detector-containerid 3.10 Ubuntu runs-on: ubuntu-latest @@ -1450,17 +1279,17 @@ jobs: run: tox -e py314-test-resource-detector-containerid -- -ra pypy3-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid pypy-3.9 Ubuntu + name: resource-detector-containerid pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -1468,44 +1297,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-resource-detector-containerid -- -ra - py39-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-azure-0 -- -ra - - py39-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-azure-1 -- -ra - py310-test-resource-detector-azure-0_ubuntu-latest: name: resource-detector-azure-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -1697,17 +1488,17 @@ jobs: run: tox -e py314-test-resource-detector-azure-1 -- -ra pypy3-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 pypy-3.9 Ubuntu + name: resource-detector-azure-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -1716,17 +1507,17 @@ jobs: run: tox -e pypy3-test-resource-detector-azure-0 -- -ra pypy3-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 pypy-3.9 Ubuntu + name: resource-detector-azure-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -1734,44 +1525,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-resource-detector-azure-1 -- -ra - py39-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-sdk-extension-aws-0 -- -ra - - py39-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-sdk-extension-aws-1 -- -ra - py310-test-sdk-extension-aws-0_ubuntu-latest: name: sdk-extension-aws-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -1963,17 +1716,17 @@ jobs: run: tox -e py314-test-sdk-extension-aws-1 -- -ra pypy3-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 pypy-3.9 Ubuntu + name: sdk-extension-aws-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -1982,17 +1735,17 @@ jobs: run: tox -e pypy3-test-sdk-extension-aws-0 -- -ra pypy3-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 pypy-3.9 Ubuntu + name: sdk-extension-aws-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2000,25 +1753,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-sdk-extension-aws-1 -- -ra - py39-test-distro_ubuntu-latest: - name: distro 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-distro -- -ra - py310-test-distro_ubuntu-latest: name: distro 3.10 Ubuntu runs-on: ubuntu-latest @@ -2115,17 +1849,17 @@ jobs: run: tox -e py314-test-distro -- -ra pypy3-test-distro_ubuntu-latest: - name: distro pypy-3.9 Ubuntu + name: distro pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2133,44 +1867,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-distro -- -ra - py39-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt1 -- -ra - - py39-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt2 -- -ra - py310-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: name: opentelemetry-instrumentation-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -2362,17 +2058,17 @@ jobs: run: tox -e py314-test-opentelemetry-instrumentation-wrapt2 -- -ra pypy3-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 pypy-3.9 Ubuntu + name: opentelemetry-instrumentation-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2380,25 +2076,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-opentelemetry-instrumentation-wrapt2 -- -ra - py39-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-client -- -ra - py310-test-instrumentation-aiohttp-client_ubuntu-latest: name: instrumentation-aiohttp-client 3.10 Ubuntu runs-on: ubuntu-latest @@ -2495,17 +2172,17 @@ jobs: run: tox -e py314-test-instrumentation-aiohttp-client -- -ra pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client pypy-3.9 Ubuntu + name: instrumentation-aiohttp-client pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2513,25 +2190,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aiohttp-client -- -ra - py39-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-server -- -ra - py310-test-instrumentation-aiohttp-server_ubuntu-latest: name: instrumentation-aiohttp-server 3.10 Ubuntu runs-on: ubuntu-latest @@ -2628,17 +2286,17 @@ jobs: run: tox -e py314-test-instrumentation-aiohttp-server -- -ra pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server pypy-3.9 Ubuntu + name: instrumentation-aiohttp-server pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2646,44 +2304,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra - py39-test-instrumentation-aiopg-wrapt1_ubuntu-latest: - name: instrumentation-aiopg-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt1 -- -ra - - py39-test-instrumentation-aiopg-wrapt2_ubuntu-latest: - name: instrumentation-aiopg-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt2 -- -ra - py310-test-instrumentation-aiopg-wrapt1_ubuntu-latest: name: instrumentation-aiopg-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -2874,25 +2494,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-aiopg-wrapt2 -- -ra - py39-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aws-lambda -- -ra - py310-test-instrumentation-aws-lambda_ubuntu-latest: name: instrumentation-aws-lambda 3.10 Ubuntu runs-on: ubuntu-latest @@ -2989,17 +2590,17 @@ jobs: run: tox -e py314-test-instrumentation-aws-lambda -- -ra pypy3-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda pypy-3.9 Ubuntu + name: instrumentation-aws-lambda pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -3007,82 +2608,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: - name: instrumentation-botocore-0-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt1 -- -ra - - py39-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: - name: instrumentation-botocore-0-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt2 -- -ra - - py39-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: - name: instrumentation-botocore-1-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt1 -- -ra - - py39-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: - name: instrumentation-botocore-1-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra - py310-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: name: instrumentation-botocore-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -3463,44 +2988,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-botocore-1-wrapt2 -- -ra - py39-test-instrumentation-botocore-2_ubuntu-latest: - name: instrumentation-botocore-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-2 -- -ra - - py39-test-instrumentation-botocore-3_ubuntu-latest: - name: instrumentation-botocore-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-3 -- -ra - py310-test-instrumentation-botocore-2_ubuntu-latest: name: instrumentation-botocore-2 3.10 Ubuntu runs-on: ubuntu-latest @@ -3691,25 +3178,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-botocore-3 -- -ra - py39-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-boto3sqs -- -ra - py310-test-instrumentation-boto3sqs_ubuntu-latest: name: instrumentation-boto3sqs 3.10 Ubuntu runs-on: ubuntu-latest @@ -3806,17 +3274,17 @@ jobs: run: tox -e py314-test-instrumentation-boto3sqs -- -ra pypy3-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs pypy-3.9 Ubuntu + name: instrumentation-boto3sqs pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -3824,65 +3292,65 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra - py39-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 3.9 Ubuntu + py310-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-0 -- -ra + run: tox -e py310-test-instrumentation-django-0 -- -ra - py39-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.9 Ubuntu + py310-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-1 -- -ra + run: tox -e py310-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-django-2_ubuntu-latest: - name: instrumentation-django-2 3.9 Ubuntu + py310-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-2 -- -ra + run: tox -e py310-test-instrumentation-django-2 -- -ra - py310-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.10 Ubuntu + py310-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3898,26 +3366,26 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-django-1 -- -ra + run: tox -e py310-test-instrumentation-django-3 -- -ra - py310-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.10 Ubuntu + py311-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-django-3 -- -ra + run: tox -e py311-test-instrumentation-django-0 -- -ra py311-test-instrumentation-django-1_ubuntu-latest: name: instrumentation-django-1 3.11 Ubuntu @@ -3938,6 +3406,25 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-django-1 -- -ra + py311-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-django-2 -- -ra + py311-test-instrumentation-django-3_ubuntu-latest: name: instrumentation-django-3 3.11 Ubuntu runs-on: ubuntu-latest @@ -3957,6 +3444,25 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-django-3 -- -ra + py312-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-django-0 -- -ra + py312-test-instrumentation-django-1_ubuntu-latest: name: instrumentation-django-1 3.12 Ubuntu runs-on: ubuntu-latest @@ -3976,6 +3482,25 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-django-1 -- -ra + py312-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-django-2 -- -ra + py312-test-instrumentation-django-3_ubuntu-latest: name: instrumentation-django-3 3.12 Ubuntu runs-on: ubuntu-latest @@ -4034,17 +3559,17 @@ jobs: run: tox -e py314-test-instrumentation-django-3 -- -ra pypy3-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 pypy-3.9 Ubuntu + name: instrumentation-django-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4053,17 +3578,17 @@ jobs: run: tox -e pypy3-test-instrumentation-django-0 -- -ra pypy3-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 pypy-3.9 Ubuntu + name: instrumentation-django-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4071,43 +3596,43 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-dbapi-wrapt1_ubuntu-latest: - name: instrumentation-dbapi-wrapt1 3.9 Ubuntu + pypy3-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt1 -- -ra + run: tox -e pypy3-test-instrumentation-django-2 -- -ra - py39-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 3.9 Ubuntu + pypy3-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra + run: tox -e pypy3-test-instrumentation-django-3 -- -ra py310-test-instrumentation-dbapi-wrapt1_ubuntu-latest: name: instrumentation-dbapi-wrapt1 3.10 Ubuntu @@ -4300,17 +3825,17 @@ jobs: run: tox -e py314-test-instrumentation-dbapi-wrapt2 -- -ra pypy3-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-dbapi-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4318,25 +3843,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-dbapi-wrapt2 -- -ra - py39-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncclick -- -ra - py310-test-instrumentation-asyncclick_ubuntu-latest: name: instrumentation-asyncclick 3.10 Ubuntu runs-on: ubuntu-latest @@ -4433,17 +3939,17 @@ jobs: run: tox -e py314-test-instrumentation-asyncclick -- -ra pypy3-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick pypy-3.9 Ubuntu + name: instrumentation-asyncclick pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4451,25 +3957,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-asyncclick -- -ra - py39-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-click -- -ra - py310-test-instrumentation-click_ubuntu-latest: name: instrumentation-click 3.10 Ubuntu runs-on: ubuntu-latest @@ -4566,17 +4053,17 @@ jobs: run: tox -e py314-test-instrumentation-click -- -ra pypy3-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click pypy-3.9 Ubuntu + name: instrumentation-click pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4584,63 +4071,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-click -- -ra - py39-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra - - py39-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra - - py39-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra - py310-test-instrumentation-elasticsearch-0_ubuntu-latest: name: instrumentation-elasticsearch-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -4927,17 +4357,17 @@ jobs: run: tox -e py314-test-instrumentation-elasticsearch-2 -- -ra pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 pypy-3.9 Ubuntu + name: instrumentation-elasticsearch-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4946,17 +4376,17 @@ jobs: run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 pypy-3.9 Ubuntu + name: instrumentation-elasticsearch-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4965,17 +4395,17 @@ jobs: run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu + name: instrumentation-elasticsearch-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4983,82 +4413,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra - py39-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra - - py39-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra - - py39-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-2 -- -ra - - py39-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-3 -- -ra - py310-test-instrumentation-falcon-1_ubuntu-latest: name: instrumentation-falcon-1 3.10 Ubuntu runs-on: ubuntu-latest @@ -5325,37 +4679,18 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-falcon-4 -- -ra - pypy3-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra - pypy3-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 pypy-3.9 Ubuntu + name: instrumentation-falcon-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5364,17 +4699,17 @@ jobs: run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra pypy3-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 pypy-3.9 Ubuntu + name: instrumentation-falcon-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5383,17 +4718,17 @@ jobs: run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra pypy3-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 pypy-3.9 Ubuntu + name: instrumentation-falcon-3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5402,17 +4737,17 @@ jobs: run: tox -e pypy3-test-instrumentation-falcon-3 -- -ra pypy3-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 pypy-3.9 Ubuntu + name: instrumentation-falcon-4 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5420,25 +4755,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-4 -- -ra - py39-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-fastapi -- -ra - py310-test-instrumentation-fastapi_ubuntu-latest: name: instrumentation-fastapi 3.10 Ubuntu runs-on: ubuntu-latest @@ -5535,17 +4851,17 @@ jobs: run: tox -e py314-test-instrumentation-fastapi -- -ra pypy3-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi pypy-3.9 Ubuntu + name: instrumentation-fastapi pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5553,82 +4869,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-fastapi -- -ra - py39-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-0 -- -ra - - py39-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-1 -- -ra - - py39-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-2 -- -ra - - py39-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-3 -- -ra - py310-test-instrumentation-flask-0_ubuntu-latest: name: instrumentation-flask-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -6010,17 +5250,17 @@ jobs: run: tox -e py314-test-instrumentation-flask-3 -- -ra pypy3-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 pypy-3.9 Ubuntu + name: instrumentation-flask-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6029,17 +5269,17 @@ jobs: run: tox -e pypy3-test-instrumentation-flask-0 -- -ra pypy3-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 pypy-3.9 Ubuntu + name: instrumentation-flask-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6047,25 +5287,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-flask-1 -- -ra - py39-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-urllib -- -ra - py310-test-instrumentation-urllib_ubuntu-latest: name: instrumentation-urllib 3.10 Ubuntu runs-on: ubuntu-latest @@ -6162,17 +5383,17 @@ jobs: run: tox -e py314-test-instrumentation-urllib -- -ra pypy3-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib pypy-3.9 Ubuntu + name: instrumentation-urllib pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6180,100 +5401,62 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-urllib -- -ra - py39-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.9 Ubuntu + py310-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.9 Ubuntu + py310-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - py310-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.10 Ubuntu + py311-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - - py310-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - - py311-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-0 -- -ra + run: tox -e py311-test-instrumentation-urllib3-0 -- -ra py311-test-instrumentation-urllib3-1_ubuntu-latest: name: instrumentation-urllib3-1 3.11 Ubuntu @@ -6371,17 +5554,17 @@ jobs: run: tox -e py313-test-instrumentation-urllib3-1 -- -ra pypy3-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 pypy-3.9 Ubuntu + name: instrumentation-urllib3-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6390,17 +5573,17 @@ jobs: run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra pypy3-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 pypy-3.9 Ubuntu + name: instrumentation-urllib3-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6408,25 +5591,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra - py39-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-requests -- -ra - py310-test-instrumentation-requests_ubuntu-latest: name: instrumentation-requests 3.10 Ubuntu runs-on: ubuntu-latest @@ -6522,44 +5686,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-requests -- -ra - py39-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-starlette-oldest -- -ra - - py39-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-starlette-latest -- -ra - py310-test-instrumentation-starlette-oldest_ubuntu-latest: name: instrumentation-starlette-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -6751,17 +5877,17 @@ jobs: run: tox -e py314-test-instrumentation-starlette-latest -- -ra pypy3-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest pypy-3.9 Ubuntu + name: instrumentation-starlette-oldest pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6770,17 +5896,17 @@ jobs: run: tox -e pypy3-test-instrumentation-starlette-oldest -- -ra pypy3-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest pypy-3.9 Ubuntu + name: instrumentation-starlette-latest pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6788,25 +5914,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-starlette-latest -- -ra - py39-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-jinja2 -- -ra - py310-test-instrumentation-jinja2_ubuntu-latest: name: instrumentation-jinja2 3.10 Ubuntu runs-on: ubuntu-latest @@ -6903,17 +6010,17 @@ jobs: run: tox -e py314-test-instrumentation-jinja2 -- -ra pypy3-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 pypy-3.9 Ubuntu + name: instrumentation-jinja2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6921,25 +6028,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-jinja2 -- -ra - py39-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-logging -- -ra - py310-test-instrumentation-logging_ubuntu-latest: name: instrumentation-logging 3.10 Ubuntu runs-on: ubuntu-latest @@ -7036,17 +6124,17 @@ jobs: run: tox -e py314-test-instrumentation-logging -- -ra pypy3-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging pypy-3.9 Ubuntu + name: instrumentation-logging pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7054,25 +6142,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-logging -- -ra - py39-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-richconsole -- -ra - py310-test-exporter-richconsole_ubuntu-latest: name: exporter-richconsole 3.10 Ubuntu runs-on: ubuntu-latest @@ -7169,17 +6238,17 @@ jobs: run: tox -e py314-test-exporter-richconsole -- -ra pypy3-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole pypy-3.9 Ubuntu + name: exporter-richconsole pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7187,25 +6256,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-exporter-richconsole -- -ra - py39-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-prometheus-remote-write -- -ra - py310-test-exporter-prometheus-remote-write_ubuntu-latest: name: exporter-prometheus-remote-write 3.10 Ubuntu runs-on: ubuntu-latest @@ -7301,7 +6351,7 @@ jobs: - name: Run tests run: tox -e py314-test-exporter-prometheus-remote-write -- -ra - pypy310-test-exporter-prometheus-remote-write_ubuntu-latest: + pypy3-test-exporter-prometheus-remote-write_ubuntu-latest: name: exporter-prometheus-remote-write pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 @@ -7318,45 +6368,7 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy310-test-exporter-prometheus-remote-write -- -ra - - py39-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysql-0 -- -ra - - py39-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra + run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra py310-test-instrumentation-mysql-0_ubuntu-latest: name: instrumentation-mysql-0 3.10 Ubuntu @@ -7549,17 +6561,17 @@ jobs: run: tox -e py314-test-instrumentation-mysql-1 -- -ra pypy3-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 pypy-3.9 Ubuntu + name: instrumentation-mysql-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7568,17 +6580,17 @@ jobs: run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra pypy3-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 pypy-3.9 Ubuntu + name: instrumentation-mysql-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7586,25 +6598,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra - py39-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra - py310-test-instrumentation-mysqlclient_ubuntu-latest: name: instrumentation-mysqlclient 3.10 Ubuntu runs-on: ubuntu-latest @@ -7701,17 +6694,17 @@ jobs: run: tox -e py314-test-instrumentation-mysqlclient -- -ra pypy3-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient pypy-3.9 Ubuntu + name: instrumentation-mysqlclient pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7719,25 +6712,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra - py310-test-instrumentation-psycopg2_ubuntu-latest: name: instrumentation-psycopg2 3.10 Ubuntu runs-on: ubuntu-latest @@ -7833,25 +6807,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-psycopg2 -- -ra - py39-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra - py310-test-instrumentation-psycopg2-binary_ubuntu-latest: name: instrumentation-psycopg2-binary 3.10 Ubuntu runs-on: ubuntu-latest @@ -7947,25 +6902,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-psycopg2-binary -- -ra - py39-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra - py310-test-instrumentation-psycopg_ubuntu-latest: name: instrumentation-psycopg 3.10 Ubuntu runs-on: ubuntu-latest @@ -8062,17 +6998,17 @@ jobs: run: tox -e py314-test-instrumentation-psycopg -- -ra pypy3-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg pypy-3.9 Ubuntu + name: instrumentation-psycopg pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8080,151 +7016,56 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-psycopg -- -ra - py39-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.9 Ubuntu + py310-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - py39-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.9 Ubuntu + py310-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - py39-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.9 Ubuntu + py310-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra - - py39-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra - - py39-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra - - py310-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - - py310-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - - py310-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" + python-version: "3.10" - name: Install tox run: pip install tox-uv @@ -8651,17 +7492,17 @@ jobs: run: tox -e py314-test-instrumentation-pymemcache-4 -- -ra pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8670,17 +7511,17 @@ jobs: run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8689,17 +7530,17 @@ jobs: run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8708,17 +7549,17 @@ jobs: run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8727,17 +7568,17 @@ jobs: run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-4 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8745,25 +7586,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra - py39-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymongo -- -ra - py310-test-instrumentation-pymongo_ubuntu-latest: name: instrumentation-pymongo 3.10 Ubuntu runs-on: ubuntu-latest @@ -8860,17 +7682,17 @@ jobs: run: tox -e py314-test-instrumentation-pymongo -- -ra pypy3-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo pypy-3.9 Ubuntu + name: instrumentation-pymongo pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8878,25 +7700,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-pymongo -- -ra - py39-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymysql -- -ra - py310-test-instrumentation-pymysql_ubuntu-latest: name: instrumentation-pymysql 3.10 Ubuntu runs-on: ubuntu-latest @@ -8993,17 +7796,17 @@ jobs: run: tox -e py314-test-instrumentation-pymysql -- -ra pypy3-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql pypy-3.9 Ubuntu + name: instrumentation-pymysql pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9011,25 +7814,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-pymysql -- -ra - py39-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymssql -- -ra - py310-test-instrumentation-pymssql_ubuntu-latest: name: instrumentation-pymssql 3.10 Ubuntu runs-on: ubuntu-latest @@ -9125,25 +7909,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-pymssql -- -ra - py39-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pyramid -- -ra - py310-test-instrumentation-pyramid_ubuntu-latest: name: instrumentation-pyramid 3.10 Ubuntu runs-on: ubuntu-latest @@ -9240,17 +8005,17 @@ jobs: run: tox -e py314-test-instrumentation-pyramid -- -ra pypy3-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid pypy-3.9 Ubuntu + name: instrumentation-pyramid pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9258,25 +8023,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-pyramid -- -ra - py39-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asgi -- -ra - py310-test-instrumentation-asgi_ubuntu-latest: name: instrumentation-asgi 3.10 Ubuntu runs-on: ubuntu-latest @@ -9373,17 +8119,17 @@ jobs: run: tox -e py314-test-instrumentation-asgi -- -ra pypy3-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi pypy-3.9 Ubuntu + name: instrumentation-asgi pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9391,44 +8137,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-asgi -- -ra - py39-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt1 -- -ra - - py39-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt2 -- -ra - py310-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: name: instrumentation-asyncpg-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -9619,25 +8327,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-asyncpg-wrapt2 -- -ra - py39-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlite3 -- -ra - py310-test-instrumentation-sqlite3_ubuntu-latest: name: instrumentation-sqlite3 3.10 Ubuntu runs-on: ubuntu-latest @@ -9734,17 +8423,17 @@ jobs: run: tox -e py314-test-instrumentation-sqlite3 -- -ra pypy3-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 pypy-3.9 Ubuntu + name: instrumentation-sqlite3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9752,25 +8441,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra - py39-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra - py310-test-instrumentation-wsgi_ubuntu-latest: name: instrumentation-wsgi 3.10 Ubuntu runs-on: ubuntu-latest @@ -9867,17 +8537,17 @@ jobs: run: tox -e py314-test-instrumentation-wsgi -- -ra pypy3-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi pypy-3.9 Ubuntu + name: instrumentation-wsgi pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9885,160 +8555,84 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-wsgi -- -ra - py39-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.9 Ubuntu + py310-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra - py39-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: - name: instrumentation-grpc-0-wrapt2 3.9 Ubuntu + py310-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra - py39-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.9 Ubuntu + py310-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra - py39-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.9 Ubuntu + py310-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra - py310-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra - - py310-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: - name: instrumentation-grpc-0-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra - - py310-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra - - py310-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra - - py311-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.11 Ubuntu + py311-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -10265,44 +8859,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-grpc-1-wrapt2 -- -ra - py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra - - py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra - py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: name: instrumentation-sqlalchemy-1 3.10 Ubuntu runs-on: ubuntu-latest @@ -10474,37 +9030,18 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-sqlalchemy-2 -- -ra - pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: - name: instrumentation-sqlalchemy-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra - pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 pypy-3.9 Ubuntu + name: instrumentation-sqlalchemy-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -10513,17 +9050,17 @@ jobs: run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 pypy-3.9 Ubuntu + name: instrumentation-sqlalchemy-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -10531,25 +9068,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra - py39-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-redis -- -ra - py310-test-instrumentation-redis_ubuntu-latest: name: instrumentation-redis 3.10 Ubuntu runs-on: ubuntu-latest @@ -10646,17 +9164,17 @@ jobs: run: tox -e py314-test-instrumentation-redis -- -ra pypy3-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis pypy-3.9 Ubuntu + name: instrumentation-redis pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -10664,25 +9182,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-redis -- -ra - py39-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-remoulade -- -ra - py310-test-instrumentation-remoulade_ubuntu-latest: name: instrumentation-remoulade 3.10 Ubuntu runs-on: ubuntu-latest @@ -10778,25 +9277,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-remoulade -- -ra - py39-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-celery -- -ra - py310-test-instrumentation-celery_ubuntu-latest: name: instrumentation-celery 3.10 Ubuntu runs-on: ubuntu-latest @@ -10893,17 +9373,17 @@ jobs: run: tox -e py314-test-instrumentation-celery -- -ra pypy3-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery pypy-3.9 Ubuntu + name: instrumentation-celery pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -10911,25 +9391,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-celery -- -ra - py39-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-system-metrics -- -ra - py310-test-instrumentation-system-metrics_ubuntu-latest: name: instrumentation-system-metrics 3.10 Ubuntu runs-on: ubuntu-latest @@ -11026,17 +9487,17 @@ jobs: run: tox -e py314-test-instrumentation-system-metrics -- -ra pypy3-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics pypy-3.9 Ubuntu + name: instrumentation-system-metrics pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11044,25 +9505,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-system-metrics -- -ra - py39-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-threading -- -ra - py310-test-instrumentation-threading_ubuntu-latest: name: instrumentation-threading 3.10 Ubuntu runs-on: ubuntu-latest @@ -11159,17 +9601,17 @@ jobs: run: tox -e py314-test-instrumentation-threading -- -ra pypy3-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading pypy-3.9 Ubuntu + name: instrumentation-threading pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11177,25 +9619,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-threading -- -ra - py39-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-tornado -- -ra - py310-test-instrumentation-tornado_ubuntu-latest: name: instrumentation-tornado 3.10 Ubuntu runs-on: ubuntu-latest @@ -11292,17 +9715,17 @@ jobs: run: tox -e py314-test-instrumentation-tornado -- -ra pypy3-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado pypy-3.9 Ubuntu + name: instrumentation-tornado pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11310,25 +9733,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-tornado -- -ra - py39-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-tortoiseorm -- -ra - py310-test-instrumentation-tortoiseorm_ubuntu-latest: name: instrumentation-tortoiseorm 3.10 Ubuntu runs-on: ubuntu-latest @@ -11425,17 +9829,17 @@ jobs: run: tox -e py314-test-instrumentation-tortoiseorm -- -ra pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm pypy-3.9 Ubuntu + name: instrumentation-tortoiseorm pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11443,82 +9847,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra - py39-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: - name: instrumentation-httpx-0-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt1 -- -ra - - py39-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt2 -- -ra - - py39-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: - name: instrumentation-httpx-1-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt1 -- -ra - - py39-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt2 -- -ra - py310-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: name: instrumentation-httpx-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -11824,17 +10152,17 @@ jobs: run: tox -e py314-test-instrumentation-httpx-1-wrapt2 -- -ra pypy3-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-httpx-0-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11843,17 +10171,17 @@ jobs: run: tox -e pypy3-test-instrumentation-httpx-0-wrapt2 -- -ra pypy3-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-httpx-1-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11861,25 +10189,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-httpx-1-wrapt2 -- -ra - py39-test-util-http_ubuntu-latest: - name: util-http 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-util-http -- -ra - py310-test-util-http_ubuntu-latest: name: util-http 3.10 Ubuntu runs-on: ubuntu-latest @@ -11976,17 +10285,17 @@ jobs: run: tox -e py314-test-util-http -- -ra pypy3-test-util-http_ubuntu-latest: - name: util-http pypy-3.9 Ubuntu + name: util-http pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11994,25 +10303,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-util-http -- -ra - py39-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-credential-provider-gcp -- -ra - py310-test-exporter-credential-provider-gcp_ubuntu-latest: name: exporter-credential-provider-gcp 3.10 Ubuntu runs-on: ubuntu-latest @@ -12108,25 +10398,6 @@ jobs: - name: Run tests run: tox -e py314-test-exporter-credential-provider-gcp -- -ra - py39-test-util-genai_ubuntu-latest: - name: util-genai 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-util-genai -- -ra - py310-test-util-genai_ubuntu-latest: name: util-genai 3.10 Ubuntu runs-on: ubuntu-latest @@ -12223,17 +10494,17 @@ jobs: run: tox -e py314-test-util-genai -- -ra pypy3-test-util-genai_ubuntu-latest: - name: util-genai pypy-3.9 Ubuntu + name: util-genai pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -12241,44 +10512,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-util-genai -- -ra - py39-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-aws-xray-0 -- -ra - - py39-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-aws-xray-1 -- -ra - py310-test-propagator-aws-xray-0_ubuntu-latest: name: propagator-aws-xray-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -12470,17 +10703,17 @@ jobs: run: tox -e py314-test-propagator-aws-xray-1 -- -ra pypy3-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 pypy-3.9 Ubuntu + name: propagator-aws-xray-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -12489,232 +10722,137 @@ jobs: run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra pypy3-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra - - py39-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.9 Ubuntu + name: propagator-aws-xray-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-ot-trace -- -ra - - py310-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-propagator-ot-trace -- -ra - - py311-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-propagator-ot-trace -- -ra - - py312-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-propagator-ot-trace -- -ra - - py313-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-propagator-ot-trace -- -ra + run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra - py314-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.14 Ubuntu + py310-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-propagator-ot-trace -- -ra + run: tox -e py310-test-propagator-ot-trace -- -ra - pypy3-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace pypy-3.9 Ubuntu + py311-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-propagator-ot-trace -- -ra + run: tox -e py311-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt1 3.9 Ubuntu + py312-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt1 -- -ra + run: tox -e py312-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 3.9 Ubuntu + py313-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt2 -- -ra + run: tox -e py313-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt1 3.9 Ubuntu + py314-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt1 -- -ra + run: tox -e py314-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 3.9 Ubuntu + pypy3-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt2 -- -ra + run: tox -e pypy3-test-propagator-ot-trace -- -ra py310-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: name: instrumentation-sio-pika-0-wrapt1 3.10 Ubuntu @@ -13097,17 +11235,17 @@ jobs: run: tox -e py314-test-instrumentation-sio-pika-1-wrapt2 -- -ra pypy3-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-sio-pika-0-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13116,17 +11254,17 @@ jobs: run: tox -e pypy3-test-instrumentation-sio-pika-0-wrapt2 -- -ra pypy3-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-sio-pika-1-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13134,82 +11272,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-sio-pika-1-wrapt2 -- -ra - py39-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra - - py39-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra - - py39-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra - - py39-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra - py310-test-instrumentation-aio-pika-0_ubuntu-latest: name: instrumentation-aio-pika-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -13591,17 +11653,17 @@ jobs: run: tox -e py314-test-instrumentation-aio-pika-3 -- -ra pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 pypy-3.9 Ubuntu + name: instrumentation-aio-pika-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13610,17 +11672,17 @@ jobs: run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 pypy-3.9 Ubuntu + name: instrumentation-aio-pika-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13629,17 +11691,17 @@ jobs: run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 pypy-3.9 Ubuntu + name: instrumentation-aio-pika-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13648,17 +11710,17 @@ jobs: run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 pypy-3.9 Ubuntu + name: instrumentation-aio-pika-3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13666,25 +11728,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra - py39-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiokafka -- -ra - py310-test-instrumentation-aiokafka_ubuntu-latest: name: instrumentation-aiokafka 3.10 Ubuntu runs-on: ubuntu-latest @@ -13781,17 +11824,17 @@ jobs: run: tox -e py314-test-instrumentation-aiokafka -- -ra pypy3-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka pypy-3.9 Ubuntu + name: instrumentation-aiokafka pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13799,25 +11842,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aiokafka -- -ra - py39-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-kafka-python -- -ra - py310-test-instrumentation-kafka-python_ubuntu-latest: name: instrumentation-kafka-python 3.10 Ubuntu runs-on: ubuntu-latest @@ -13856,25 +11880,6 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-kafka-python -- -ra - py39-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra - py310-test-instrumentation-kafka-pythonng_ubuntu-latest: name: instrumentation-kafka-pythonng 3.10 Ubuntu runs-on: ubuntu-latest @@ -13971,17 +11976,17 @@ jobs: run: tox -e py314-test-instrumentation-kafka-pythonng -- -ra pypy3-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python pypy-3.9 Ubuntu + name: instrumentation-kafka-python pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13990,17 +11995,17 @@ jobs: run: tox -e pypy3-test-instrumentation-kafka-python -- -ra pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng pypy-3.9 Ubuntu + name: instrumentation-kafka-pythonng pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -14008,25 +12013,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra - py39-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-confluent-kafka -- -ra - py310-test-instrumentation-confluent-kafka_ubuntu-latest: name: instrumentation-confluent-kafka 3.10 Ubuntu runs-on: ubuntu-latest @@ -14122,25 +12108,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-confluent-kafka -- -ra - py39-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncio -- -ra - py310-test-instrumentation-asyncio_ubuntu-latest: name: instrumentation-asyncio 3.10 Ubuntu runs-on: ubuntu-latest @@ -14236,44 +12203,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-asyncio -- -ra - py39-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-driver -- -ra - - py39-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-scylla -- -ra - py310-test-instrumentation-cassandra-driver_ubuntu-latest: name: instrumentation-cassandra-driver 3.10 Ubuntu runs-on: ubuntu-latest @@ -14465,17 +12394,17 @@ jobs: run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu + name: instrumentation-cassandra-scylla pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -14483,25 +12412,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra - py39-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra - py310-test-processor-baggage_ubuntu-latest: name: processor-baggage 3.10 Ubuntu runs-on: ubuntu-latest @@ -14598,17 +12508,17 @@ jobs: run: tox -e py314-test-processor-baggage -- -ra pypy3-test-processor-baggage_ubuntu-latest: - name: processor-baggage pypy-3.9 Ubuntu + name: processor-baggage pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -14616,44 +12526,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-processor-baggage -- -ra - py39-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opamp-client-latest -- -ra - - py39-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opamp-client-lowest -- -ra - py310-test-opamp-client-latest_ubuntu-latest: name: opamp-client-latest 3.10 Ubuntu runs-on: ubuntu-latest diff --git a/.pylintrc b/.pylintrc index 33fcdc1983b..17f53f20985 100644 --- a/.pylintrc +++ b/.pylintrc @@ -46,7 +46,7 @@ suggestion-mode=yes unsafe-load-any-extension=no # Run python dependant checks considering the baseline version -py-version=3.9 +py-version=3.10 [MESSAGES CONTROL] @@ -76,11 +76,11 @@ disable=missing-docstring, exec-used, super-with-arguments, # temp-pylint-upgrade isinstance-second-argument-not-valid-type, # temp-pylint-upgrade - raise-missing-from, # temp-pylint-upgrade - unused-argument, # temp-pylint-upgrade - protected-access, # temp-pylint-upgrade + raise-missing-from, # temp-pylint-upgrade + unused-argument, # temp-pylint-upgrade + protected-access, # temp-pylint-upgrade super-init-not-called, # temp-pylint-upgrade - invalid-overridden-method, # temp-pylint-upgrade + invalid-overridden-method, # temp-pylint-upgrade missing-module-docstring, # temp-pylint-upgrade import-error, # needed as a workaround as reported here: https://github.com/open-telemetry/opentelemetry-python-contrib/issues/290 cyclic-import, diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c108e893e2..6dca6b771e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Breaking changes + +- Drop Python 3.9 support + ([#4412](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4412)) + ## Version 1.41.0/0.62b0 (2026-04-09) - + ### Added - `opentelemetry-instrumentation-asgi`: Respect `suppress_http_instrumentation` context in ASGI middleware to skip server span creation when HTTP instrumentation is suppressed @@ -45,7 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-grpc`: Fix bidirectional streaming RPCs raising `AttributeError: 'generator' object has no attribute 'add_done_callback'` ([#4259](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4259)) - `opentelemetry-instrumentation-aiokafka`: fix `Unclosed AIOKafkaProducer` warning and `RuntimeWarning: coroutine was never awaited` in tests - ([#4384](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4384)) + ([#4384](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4384)) - `opentelemetry-instrumentation-aiokafka`: Fix compatibility with aiokafka 0.13 by calling `_key_serializer`/`_value_serializer` directly instead of the internal `_serialize` method whose signature changed in 0.13 from `(topic, key, value)` to `(key, value, headers)` diff --git a/_template/pyproject.toml b/_template/pyproject.toml index c9f3ba3ed13..c579035d5ff 100644 --- a/_template/pyproject.toml +++ b/_template/pyproject.toml @@ -12,7 +12,7 @@ dynamic = ["version"] description = "" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -22,7 +22,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/dev-requirements.txt b/dev-requirements.txt index b2de8cecfce..29325a6d352 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -13,6 +13,5 @@ codespell==2.1.0 requests==2.32.3 ruamel.yaml==0.17.21 flaky==3.7.0 -pre-commit==3.7.0; python_version >= '3.9' -pre-commit==3.5.0; python_version < '3.9' +pre-commit==3.7.0 ruff==0.14.1 diff --git a/exporter/opentelemetry-exporter-credential-provider-gcp/pyproject.toml b/exporter/opentelemetry-exporter-credential-provider-gcp/pyproject.toml index 5eb6b7096be..d53c8e4a0a3 100644 --- a/exporter/opentelemetry-exporter-credential-provider-gcp/pyproject.toml +++ b/exporter/opentelemetry-exporter-credential-provider-gcp/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "GCP OTLP Exporter Credential Provider for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile b/exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile index 8b2d34d4214..4bde0b14bb0 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9 +FROM python:3.10 RUN apt-get update -y && apt-get install libsnappy-dev -y diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml index 40db4fc2551..285d0b22c64 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml @@ -9,7 +9,7 @@ dynamic = ["version"] description = "Prometheus Remote Write Metrics Exporter for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -19,7 +19,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 64f3589520d..805e28340a6 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Rich Console Exporter for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml index 5cc6754ef79..6b0d72c3343 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Anthropic instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py index b2055a525f4..067ef0085e8 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py @@ -405,13 +405,13 @@ async def test_async_stream_wrapper_processes_events_and_stops_on_completion(): wrapper._process_chunk = processed.append wrapper._stop = lambda: stopped.append(True) - result = await wrapper.__anext__() + result = await anext(wrapper) assert result is event assert processed == [event] with pytest.raises(StopAsyncIteration): - await wrapper.__anext__() + await anext(wrapper) assert stopped == [True] @@ -428,7 +428,7 @@ async def test_async_stream_wrapper_fails_and_reraises_stream_errors(): ) with pytest.raises(ValueError, match="boom"): - await wrapper.__anext__() + await anext(wrapper) assert failures == [("boom", ValueError)] diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml index 87b30343e33..2ea01de4f39 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml @@ -22,7 +22,7 @@ dynamic = ["version"] description = "OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -70,4 +70,4 @@ exclude = ["**/__pycache__"] stubPath = "types" reportMissingImports = "error" reportMissingTypeStubs = false -pythonVersion = "3.9" +pythonVersion = "3.10" diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/test_e2e.py b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/test_e2e.py index 47abf4b877f..c29fe28bd14 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/test_e2e.py +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/test_e2e.py @@ -24,11 +24,9 @@ output is the purview of the other tests in this directory.""" import asyncio -import gzip import json import os import subprocess -import sys import time import fsspec @@ -258,51 +256,6 @@ def _convert_body_to_literal(data): return data -# Helper for enforcing GZIP compression where it was originally. -def _ensure_gzip_single_response(data: bytes): - try: - # Attempt to decompress, first, to avoid double compression. - gzip.decompress(data) - return data - except gzip.BadGzipFile: - # It must not have been compressed in the first place. - return gzip.compress(data) - - -# VCRPy automatically decompresses responses before saving them, but it may forget to -# re-encode them when the data is loaded. This can create issues with decompression. -# This is why we re-encode on load; to accurately replay what was originally sent. -# -# https://vcrpy.readthedocs.io/en/latest/advanced.html#decode-compressed-response -def _ensure_casette_gzip(loaded_casette): - for interaction in loaded_casette["interactions"]: - response = interaction["response"] - headers = response["headers"] - if ( - "content-encoding" not in headers - and "Content-Encoding" not in headers - ): - continue - if ( - "content-encoding" in headers - and "gzip" not in headers["content-encoding"] - ): - continue - if ( - "Content-Encoding" in headers - and "gzip" not in headers["Content-Encoding"] - ): - continue - response["body"]["string"] = _ensure_gzip_single_response( - response["body"]["string"].encode() - ) - - -def _maybe_ensure_casette_gzip(result): - if sys.version_info[0] == 3 and sys.version_info[1] == 9: - _ensure_casette_gzip(result) - - class _PrettyPrintJSONBody: """This makes request and response body recordings more readable.""" @@ -315,9 +268,7 @@ def serialize(cassette_dict): @staticmethod def deserialize(cassette_string): - result = yaml.load(cassette_string, Loader=yaml.Loader) - _maybe_ensure_casette_gzip(result) - return result + return yaml.load(cassette_string, Loader=yaml.Loader) @pytest.fixture(name="fully_initialized_vcr", scope="module", autouse=True) diff --git a/instrumentation-genai/opentelemetry-instrumentation-langchain/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-langchain/pyproject.toml index 13947d25550..80a406b7dae 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-langchain/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-langchain/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official Langchain instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml index 61a63e60bf7..e87c28d879a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official OpenAI Agents instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index 7b4fcce2241..807d5bf9981 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official OpenAI instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py index 2789284b887..3061a23f3a7 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py @@ -371,13 +371,13 @@ async def test_async_stream_wrapper_processes_events_and_stops_on_completion(): wrapper.process_event = processed.append wrapper._stop = stopped.append - result = await wrapper.__anext__() + result = await anext(wrapper) assert result is event assert processed == [event] with pytest.raises(StopAsyncIteration): - await wrapper.__anext__() + await anext(wrapper) assert stopped == [None] @@ -416,7 +416,7 @@ def record_failure(message, error_type): wrapper._fail = record_failure with pytest.raises(ValueError, match="boom"): - await wrapper.__anext__() + await anext(wrapper) assert failures == [("boom", ValueError)] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml index e6090642f6d..91a58956989 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official VertexAI instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-weaviate/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-weaviate/pyproject.toml index 2489c378957..7ff31901dee 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-weaviate/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-weaviate/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official Weaviate Client Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 7eb7f04f2ce..2f57713d0de 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Aio-pika instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index ef895020ab6..f908184beb3 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry aiohttp client instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index 779db188c4b..6c1d86d8fab 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Aiohttp server instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io"} ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml index 9c9827a3c0e..52714ef384a 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry aiokafka instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py index 646232da356..e0812fe1c52 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py @@ -14,10 +14,9 @@ from __future__ import annotations -import sys import uuid from typing import Any, Sequence, cast -from unittest import IsolatedAsyncioTestCase, TestCase, mock, skipIf +from unittest import IsolatedAsyncioTestCase, TestCase, mock import aiokafka from aiokafka import ( @@ -64,10 +63,6 @@ def test_instrument_api(self) -> None: ) -@skipIf( - sys.version_info < (3, 10), - "aiokafka >= 0.13 requires Python 3.10+", -) class TestAIOKafkaInstrumentation(TestBase, IsolatedAsyncioTestCase): @staticmethod def consumer_record_factory( @@ -266,21 +261,12 @@ async def async_consume_hook(span, *_) -> None: async def test_getone_consume_hook(self) -> None: async_consume_hook_mock = mock.AsyncMock() - def is_async_consume_hook_mock(obj: Any) -> bool: - return obj is async_consume_hook_mock - AIOKafkaInstrumentor().uninstrument() - # TODO: remove mock.patch when we drop Python 3.9 support - with mock.patch( - "opentelemetry.instrumentation.aiokafka.iscoroutinefunction" - ) as iscoro: - iscoro.side_effect = is_async_consume_hook_mock - - AIOKafkaInstrumentor().instrument( - tracer_provider=self.tracer_provider, - async_consume_hook=async_consume_hook_mock, - ) + AIOKafkaInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_consume_hook=async_consume_hook_mock, + ) consumer = await self.consumer_factory() self.addAsyncCleanup(consumer.stop) @@ -463,20 +449,11 @@ async def test_send_baggage(self) -> None: async def test_send_produce_hook(self) -> None: async_produce_hook_mock = mock.AsyncMock() - def is_async_produce_hook_mock(obj: Any) -> bool: - return obj is async_produce_hook_mock - AIOKafkaInstrumentor().uninstrument() - # TODO: remove mock.patch when we drop Python 3.9 support - with mock.patch( - "opentelemetry.instrumentation.aiokafka.iscoroutinefunction" - ) as iscoro: - iscoro.side_effect = is_async_produce_hook_mock - - AIOKafkaInstrumentor().instrument( - tracer_provider=self.tracer_provider, - async_produce_hook=async_produce_hook_mock, - ) + AIOKafkaInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_produce_hook=async_produce_hook_mock, + ) producer = await self.producer_factory() self.addAsyncCleanup(producer.stop) diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 13bf30b54cd..37327d50edc 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry aiopg instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index 24e3debff17..36ffeba0bc8 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "ASGI instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml index b2a3e5c397b..16cc5299653 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Async Click instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index e30dc7821c2..c1a42b4ed1c 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry instrumentation for asyncio" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py index f964044fc7b..a89134ca9b8 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. import asyncio -import sys -from unittest import skipIf from unittest.mock import patch # pylint: disable=no-name-in-module @@ -44,9 +42,6 @@ def tearDown(self): # Asyncio anext() does not have __name__ attribute, which is used to determine if the coroutine should be traced. # This test is to ensure that the instrumentation does not break when the coroutine does not have __name__ attribute. # Additionally, ensure the coroutine is actually awaited. - @skipIf( - sys.version_info < (3, 10), "anext is only available in Python 3.10+" - ) def test_asyncio_anext(self): async def main(): async def async_gen(): diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index 589fd11903e..62b83f4b762 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry instrumentation for AsyncPG" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py index 21d4591e0e7..f8c905a2c79 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py @@ -106,7 +106,7 @@ async def exec_mock(*args, **kwargs): ) with pytest.raises(StopAsyncIteration): - asyncio.run(crs_iter.__anext__()) + asyncio.run(anext(crs_iter)) spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index ba0b4e3e422..e73c3f99262 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry AWS Lambda instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index f373fd189bf..d649734720d 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Boto3 SQS service tracing for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index fa5e8850f77..5dd212a31bf 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Botocore instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py index 3ff8ca7f223..4c3295c45d3 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py @@ -113,7 +113,7 @@ def _create_lambda_function(self, function_name: str, function_code: str): self.client.create_function( FunctionName=function_name, - Runtime="python3.9", + Runtime="python3.10", Role=role_arn, Handler="lambda_function.lambda_handler", Code={ diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 60200cce006..6b51889b3c1 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Cassandra instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index b60271f42b9..21a58ea35e9 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Celery Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml index 3e36f50e3e5..2fbcdf19c03 100644 --- a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Click instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 87ac6c59669..6958b515ad9 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Confluent Kafka instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index db9d0b053d0..225f9cf97ba 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Database API instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index d0d5090ab3b..56c624d3d51 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Instrumentation for Django" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index de46d416348..0ad78d45166 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -12,6 +12,7 @@ tomli==2.0.1 typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 +setuptools==79.0.1 ; python_version >= "3.12" -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index f7d12ec741e..40c6756d835 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -1,5 +1,4 @@ asgiref==3.8.1 -backports.zoneinfo==0.2.1 Deprecated==1.2.14 Django==4.2.17 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index 8b44950fc9a..c7b962ae5af 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry elasticsearch instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index c4a59473d52..5eb789a5c7a 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Falcon instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 7159b2a01c5..c76d0f351c4 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry FastAPI Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index 08a7366e3f0..4b43789e6c1 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Flask instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py index f69470ab9ed..ced6c8c6f7c 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -254,7 +254,6 @@ def response_hook(span: Span, status: str, response_headers: List): --- """ -import sys import weakref from logging import getLogger from time import time_ns @@ -582,14 +581,8 @@ def _teardown_request(exc): try: # For Flask 3.1+, check if this is a streaming response that might # have already been cleaned up to prevent double cleanup - # Only check for streaming in Flask 3.1+ and Python 3.10+ to avoid interference with older versions - is_flask_31_plus = _IS_FLASK_31_PLUS and sys.version_info >= ( - 3, - 10, - ) - is_streaming = False - if is_flask_31_plus: + if _IS_FLASK_31_PLUS: try: # Additional safety check: verify we're in a Flask request context if hasattr(flask, "request") and hasattr( @@ -605,7 +598,7 @@ def _teardown_request(exc): # Not in a proper Flask request context, don't check for streaming is_streaming = False - if is_flask_31_plus and is_streaming: + if _IS_FLASK_31_PLUS and is_streaming: # For Flask 3.1+ streaming responses, ensure OpenTelemetry contexts are cleaned up # This addresses the generator context leak issues documented by Logfire # (open-telemetry/opentelemetry-python#2606) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_flask_compatibility.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_flask_compatibility.py index dcf9b2bdd61..8e1804038b6 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_flask_compatibility.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_flask_compatibility.py @@ -18,7 +18,6 @@ """ import io -import sys import threading import time from unittest import mock, skipIf @@ -297,10 +296,6 @@ def generate(): self.assertEqual(response.status_code, 200) self.assertEqual(response.data, b"Data") - @skipIf( - sys.version_info < (3, 10), - "Flask 3.1+ streaming context cleanup only enabled on Python 3.10+", - ) @skipIf( lambda: ( not __import__( diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index adcfa7afd79..17df13ef8ec 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry gRPC instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 7b356b50789..f07cca6ca4a 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry HTTPX Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index ed6cb19b9fc..70f36f5030e 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry jinja2 instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index ac883738d47..141c72c56f2 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Kafka-Python instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index de216965c81..f14d2e90ead 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Logging instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index e780d5ab297..f58c79a4dd3 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry MySQL instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index e732ccb1491..4d2ba6aca39 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry mysqlclient instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 5679a9799c6..8c7c6436962 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry pika instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 322e86d2811..ace2acb412d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry psycopg instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index 601b6489184..b96dfe23141 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry psycopg2 instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index 73c9829a31f..fcb0dfd74aa 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry pymemcache instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index a58af7ec205..759c9b86491 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry pymongo instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml index c29c392bebc..a97c708b15b 100644 --- a/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry pymssql instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index 9dfc439e009..43d72e03ff9 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry PyMySQL instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 7d1450e83f0..0268d0cd022 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Pyramid instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index 2277a7f8a50..19c5e194f95 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Redis instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index 5e00fa48cfc..199bee6b0f8 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Remoulade instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index d0ddab1e3cd..7f18d26879a 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry requests instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index 1e69d56ac62..34317db4b07 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry SQLAlchemy instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index b941f926e26..f837ac585d5 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry SQLite3 instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 518014039bd..298ea6252a2 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Starlette Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt index e1057fed607..280667dffea 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.9 --universal --no-emit-package opentelemetry-api --no-emit-package opentelemetry-semantic-conventions -c dev-requirements.txt instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in -o instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt +# uv pip compile --python 3.10 --universal --no-emit-package opentelemetry-api --no-emit-package opentelemetry-semantic-conventions -c dev-requirements.txt instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in -o instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt -e instrumentation/opentelemetry-instrumentation-asgi # via # -r instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in @@ -16,11 +16,7 @@ # -r instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in # opentelemetry-instrumentation-asgi # opentelemetry-instrumentation-starlette -anyio==4.5.2 ; python_full_version < '3.9' - # via - # httpx - # starlette -anyio==4.8.0 ; python_full_version >= '3.9' +anyio==4.8.0 # via # httpx # starlette @@ -70,9 +66,7 @@ requests==2.32.3 # -r instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in sniffio==1.3.1 # via anyio -starlette==0.44.0 ; python_full_version < '3.9' - # via opentelemetry-instrumentation-starlette -starlette==0.46.2 ; python_full_version >= '3.9' +starlette==0.46.2 # via opentelemetry-instrumentation-starlette tomli==2.2.1 ; python_full_version < '3.11' # via pytest @@ -82,16 +76,11 @@ typing-extensions==4.12.2 # asgiref # opentelemetry-api # opentelemetry-semantic-conventions - # starlette -urllib3==2.2.3 ; python_full_version < '3.9' - # via requests -urllib3==2.3.0 ; python_full_version >= '3.9' +urllib3==2.3.0 # via requests wrapt==1.14.1 # via opentelemetry-instrumentation -zipp==3.20.2 ; python_full_version < '3.9' - # via importlib-metadata -zipp==3.21.0 ; python_full_version >= '3.9' +zipp==3.21.0 # via importlib-metadata # The following packages were excluded from the output: diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt index 99fd4853e98..79dbf0ec769 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.9 --universal --resolution lowest-direct --no-emit-package opentelemetry-api --no-emit-package opentelemetry-semantic-conventions -c dev-requirements.txt instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in -o instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt +# uv pip compile --python 3.10 --universal --resolution lowest-direct --no-emit-package opentelemetry-api --no-emit-package opentelemetry-semantic-conventions -c dev-requirements.txt instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in -o instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt -e instrumentation/opentelemetry-instrumentation-asgi # via # -r instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in @@ -29,10 +29,6 @@ charset-normalizer==3.4.1 # via requests colorama==0.4.6 ; sys_platform == 'win32' # via pytest -deprecated==1.2.14 - # via - # opentelemetry-api - # opentelemetry-semantic-conventions exceptiongroup==1.2.2 ; python_full_version < '3.11' # via # anyio @@ -72,16 +68,16 @@ starlette==0.13.8 # via opentelemetry-instrumentation-starlette tomli==2.2.1 ; python_full_version < '3.11' # via pytest -typing-extensions==4.12.2 ; python_full_version < '3.13' +typing-extensions==4.12.2 # via # anyio # asgiref + # opentelemetry-api + # opentelemetry-semantic-conventions urllib3==2.3.0 # via requests wrapt==1.16.0 - # via - # deprecated - # opentelemetry-instrumentation + # via opentelemetry-instrumentation zipp==3.21.0 # via importlib-metadata diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 0d2aa6d658b..3060eaa03c5 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry System Metrics Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 66e2a1b8d9f..9f5818117b5 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Thread context propagation support for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index 04890fa6077..5dfb3744c37 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Tornado instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -17,7 +17,6 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index 5c0ea288b8e..ee743301b07 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Instrumentation for Tortoise ORM" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 258e28848db..96e96131896 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry urllib instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index 0e3e2c5f990..8da041e5046 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry urllib3 instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index 6fcdeb58684..c008090b639 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "WSGI Middleware for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/opamp/opentelemetry-opamp-client/pyproject.toml b/opamp/opentelemetry-opamp-client/pyproject.toml index 978878c6207..4d223f77ed3 100644 --- a/opamp/opentelemetry-opamp-client/pyproject.toml +++ b/opamp/opentelemetry-opamp-client/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry OpAMP client" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/opamp/opentelemetry-opamp-client/test-requirements.latest.txt b/opamp/opentelemetry-opamp-client/test-requirements.latest.txt index 8c2e2951286..68196f99924 100644 --- a/opamp/opentelemetry-opamp-client/test-requirements.latest.txt +++ b/opamp/opentelemetry-opamp-client/test-requirements.latest.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.9 --universal -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.latest.txt +# uv pip compile --python 3.10 --universal -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.latest.txt --no-emit-package opentelemetry-api -e opamp/opentelemetry-opamp-client # via -r opamp/opentelemetry-opamp-client/test-requirements.in certifi==2025.7.9 @@ -43,7 +43,7 @@ pytest==7.4.4 # -c dev-requirements.txt # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest-vcr -pytest-vcr==1.0.2 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' +pytest-vcr==1.0.2 ; platform_python_implementation != 'PyPy' # via -r opamp/opentelemetry-opamp-client/test-requirements.in pyyaml==6.0.2 # via @@ -71,7 +71,7 @@ uuid-utils==0.11.0 # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # opentelemetry-opamp-client -vcrpy==7.0.0 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' +vcrpy==7.0.0 ; platform_python_implementation != 'PyPy' # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest-vcr @@ -85,3 +85,6 @@ yarl==1.20.1 # vcrpy zipp==3.23.0 # via importlib-metadata + +# The following packages were excluded from the output: +# opentelemetry-api diff --git a/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt b/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt index 2ab1d9826eb..44acbe65ec7 100644 --- a/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt +++ b/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.9 --universal --resolution lowest -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.lowest.txt +# uv pip compile --python 3.10 --universal --resolution lowest -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.lowest.txt --no-emit-package opentelemetry-api -e opamp/opentelemetry-opamp-client # via -r opamp/opentelemetry-opamp-client/test-requirements.in certifi==2017.4.17 @@ -43,7 +43,7 @@ pytest==7.4.4 # -c dev-requirements.txt # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest-vcr -pytest-vcr==1.0.2 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' +pytest-vcr==1.0.2 ; platform_python_implementation != 'PyPy' # via -r opamp/opentelemetry-opamp-client/test-requirements.in pyyaml==6.0.2 # via @@ -68,7 +68,7 @@ uuid-utils==0.11.0 # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # opentelemetry-opamp-client -vcrpy==7.0.0 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' +vcrpy==7.0.0 ; platform_python_implementation != 'PyPy' # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest-vcr @@ -81,3 +81,6 @@ yarl==1.20.1 # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # vcrpy + +# The following packages were excluded from the output: +# opentelemetry-api diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py index 1bb9df6a4cc..745fb63faa1 100644 --- a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py @@ -13,7 +13,6 @@ # limitations under the License. import logging -import sys from time import sleep from unittest import mock @@ -25,10 +24,6 @@ from opentelemetry._opamp.proto import opamp_pb2 -@pytest.mark.skipif( - sys.version_info < (3, 10), - reason="vcr.py not working with urllib 2 and older Pythons", -) @pytest.mark.vcr() def test_connection_remote_config_status_heartbeat_disconnection(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") @@ -96,10 +91,6 @@ def on_message(self, agent, client, message): ] -@pytest.mark.skipif( - sys.version_info < (3, 10), - reason="vcr.py not working with urllib 2 and older Pythons", -) @pytest.mark.vcr() def test_with_server_not_responding(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 76713cfe12d..630509a4b2a 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -12,7 +12,7 @@ dynamic = [ description = "OpenTelemetry Contrib Instrumentation Packages" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -22,7 +22,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index 538237ea031..432ed1264d0 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Python Distro" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index 00de032a445..5a472d774e5 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/processor/opentelemetry-processor-baggage/pyproject.toml b/processor/opentelemetry-processor-baggage/pyproject.toml index 31f8ddfb7a5..f11bbd36094 100644 --- a/processor/opentelemetry-processor-baggage/pyproject.toml +++ b/processor/opentelemetry-processor-baggage/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Baggage Span Processor" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml index 0f7240efa6a..66f7d69550f 100644 --- a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml +++ b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "AWS X-Ray Propagator for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml index 74f15033319..3569d4842af 100644 --- a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml +++ b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OT Trace Propagator for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/pyproject.toml b/pyproject.toml index c877d5f0380..92cfe8b5d20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ [project] name = "opentelemetry-python-contrib" version = "0.0.0" # This is not used. -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ "opentelemetry-api", "opentelemetry-sdk", @@ -154,7 +154,7 @@ members = [ [tool.ruff] # https://docs.astral.sh/ruff/configuration/ -target-version = "py39" +target-version = "py310" line-length = 79 extend-exclude = ["_template", "*_pb2*.py*"] output-format = "concise" @@ -196,7 +196,7 @@ known-third-party = [ typeCheckingMode = "strict" reportUnnecessaryTypeIgnoreComment = true reportMissingTypeStubs = false -pythonVersion = "3.9" +pythonVersion = "3.10" reportPrivateUsage = false # Ignore private attributes added by instrumentation packages. # Add progressively instrumentation packages here. include = [ diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index b6c27d71323..99c5cebb96f 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Azure Resource Detector for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/resource/opentelemetry-resource-detector-containerid/pyproject.toml b/resource/opentelemetry-resource-detector-containerid/pyproject.toml index 46875adb09f..de1ec197179 100644 --- a/resource/opentelemetry-resource-detector-containerid/pyproject.toml +++ b/resource/opentelemetry-resource-detector-containerid/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Container Resource Detector for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml index 10e18b9ef11..716c3f1204a 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml +++ b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "AWS SDK extension for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/tox.ini b/tox.ini index 8d8d86305b7..1f2ca7f8e90 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ envlist = ; for specifying supported Python versions per package. ; instrumentation-openai - py3{9,10,11,12,13,14}-test-instrumentation-openai-v2-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-openai-v2-{oldest,latest} py313-test-instrumentation-openai-v2-pydantic1 pypy3-test-instrumentation-openai-v2-{oldest,latest} lint-instrumentation-openai-v2 @@ -19,19 +19,19 @@ envlist = lint-instrumentation-openai_agents-v2 ; instrumentation-vertexai - py3{9,10,11,12,13,14}-test-instrumentation-vertexai-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-vertexai-{oldest,latest} # Disabling pypy3 as shapely does not have wheels and fails to compile # pypy3-test-instrumentation-vertexai-{oldest,latest} lint-instrumentation-vertexai ; instrumentation-google-genai - py3{9,10,11,12,13,14}-test-instrumentation-google-genai-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-google-genai-{oldest,latest} # Disabling pypy3 as shapely does not have wheels and fails to compile # pypy3-test-instrumentation-google-genai-{0,1} lint-instrumentation-google-genai ; instrumentation-anthropic - py3{9,10,11,12,13,14}-test-instrumentation-anthropic-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-anthropic-{oldest,latest} # Disabling pypy3 as jiter (anthropic dep) requires PyPy 3.11+ # pypy3-test-instrumentation-anthropic-{oldest,latest} lint-instrumentation-anthropic @@ -43,60 +43,60 @@ envlist = lint-instrumentation-claude-agent-sdk ; opentelemetry-resource-detector-containerid - py3{9,10,11,12,13,14}-test-resource-detector-containerid + py3{10,11,12,13,14}-test-resource-detector-containerid pypy3-test-resource-detector-containerid lint-resource-detector-containerid ; opentelemetry-resource-detector-azure - py3{9,10,11,12,13,14}-test-resource-detector-azure-{0,1} + py3{10,11,12,13,14}-test-resource-detector-azure-{0,1} pypy3-test-resource-detector-azure-{0,1} lint-resource-detector-azure ; opentelemetry-sdk-extension-aws - py3{9,10,11,12,13,14}-test-sdk-extension-aws-{0,1} + py3{10,11,12,13,14}-test-sdk-extension-aws-{0,1} pypy3-test-sdk-extension-aws-{0,1} lint-sdk-extension-aws benchmark-sdk-extension-aws ; opentelemetry-distro - py3{9,10,11,12,13,14}-test-distro + py3{10,11,12,13,14}-test-distro pypy3-test-distro lint-distro ; opentelemetry-instrumentation - py3{9,10,11,12,13,14}-test-opentelemetry-instrumentation-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-opentelemetry-instrumentation-{wrapt1,wrapt2} pypy3-test-opentelemetry-instrumentation-wrapt2 lint-opentelemetry-instrumentation ; opentelemetry-instrumentation-aiohttp-client - py3{9,10,11,12,13,14}-test-instrumentation-aiohttp-client + py3{10,11,12,13,14}-test-instrumentation-aiohttp-client pypy3-test-instrumentation-aiohttp-client lint-instrumentation-aiohttp-client ; opentelemetry-instrumentation-aiohttp-server - py3{9,10,11,12,13,14}-test-instrumentation-aiohttp-server + py3{10,11,12,13,14}-test-instrumentation-aiohttp-server pypy3-test-instrumentation-aiohttp-server lint-instrumentation-aiohttp-server ; opentelemetry-instrumentation-aiopg - py3{9,10,11,12,13,14}-test-instrumentation-aiopg-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-aiopg-{wrapt1,wrapt2} ; instrumentation-aiopg intentionally excluded from pypy3 lint-instrumentation-aiopg ; opentelemetry-instrumentation-aws-lambda - py3{9,10,11,12,13,14}-test-instrumentation-aws-lambda + py3{10,11,12,13,14}-test-instrumentation-aws-lambda pypy3-test-instrumentation-aws-lambda lint-instrumentation-aws-lambda ; opentelemetry-instrumentation-botocore - py3{9,10,11,12,13,14}-test-instrumentation-botocore-{0,1}-{wrapt1,wrapt2} - py3{9,10,11,12,13,14}-test-instrumentation-botocore-{2,3} + py3{10,11,12,13,14}-test-instrumentation-botocore-{0,1}-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-botocore-{2,3} ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 ; pypy3-test-instrumentation-botocore lint-instrumentation-botocore ; opentelemetry-instrumentation-boto3sqs - py3{9,10,11,12,13,14}-test-instrumentation-boto3sqs + py3{10,11,12,13,14}-test-instrumentation-boto3sqs pypy3-test-instrumentation-boto3sqs lint-instrumentation-boto3sqs @@ -108,26 +108,25 @@ envlist = ; below mean these dependencies are being used: ; 0: django~=2.0 ; 1: django~=3.0 - ; 2: django>=4.0b1,<5.0 backports.zoneinfo==0.2.1 + ; 2: django~=4.0 ; 3: django>=5.2<6.0 - py3{9}-test-instrumentation-django-{0,1,2} - py3{10,11,12}-test-instrumentation-django-{1,3} + py3{10,11,12}-test-instrumentation-django-{0,1,2,3} py3{13,14}-test-instrumentation-django-3 - pypy3-test-instrumentation-django-{0,1} + pypy3-test-instrumentation-django-{0,1,2,3} lint-instrumentation-django ; opentelemetry-instrumentation-dbapi - py3{9,10,11,12,13,14}-test-instrumentation-dbapi-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-dbapi-{wrapt1,wrapt2} pypy3-test-instrumentation-dbapi-wrapt2 lint-instrumentation-dbapi ; opentelemetry-instrumentation-asyncclick - py3{9,10,11,12,13,14}-test-instrumentation-asyncclick + py3{10,11,12,13,14}-test-instrumentation-asyncclick pypy3-test-instrumentation-asyncclick lint-instrumentation-asyncclick ; opentelemetry-instrumentation-click - py3{9,10,11,12,13,14}-test-instrumentation-click + py3{10,11,12,13,14}-test-instrumentation-click pypy3-test-instrumentation-click lint-instrumentation-click @@ -137,28 +136,25 @@ envlist = ; 0: elasticsearch-dsl==6.4.0 elasticsearch==6.8.2 ; 1: elasticsearch-dsl==7.4.1 elasticsearch==7.17.9 ; 2: elasticsearch-dsl==8.13.1 elasticsearch==8.13.1 - py3{9,10,11,12,13,14}-test-instrumentation-elasticsearch-{0,1,2} + py3{10,11,12,13,14}-test-instrumentation-elasticsearch-{0,1,2} pypy3-test-instrumentation-elasticsearch-{0,1,2} lint-instrumentation-elasticsearch ; opentelemetry-instrumentation-falcon - ; py310 does not work with falcon 1 - ; py3{9} will be dropped for falcon 4 + ; TODO: py310 does not work with falcon 1 - Drop requirements-0.txt and bump supported version to >2 ; The numbers at the end of the environment names ; below mean these dependencies are being used: - ; 0: falcon ==1.4.1 ; 1: falcon >=2.0.0,<3.0.0 ; 2: falcon >=3.0.0,<3.1.2 ; 3: falcon >=3.1.2,<4.0.0 ; 4: falcon >=4.0.0,<5.0.0 - py3{9}-test-instrumentation-falcon-{0,1,2,3} py3{10,11,12}-test-instrumentation-falcon-{1,2,3,4} py3{13,14}-test-instrumentation-falcon-4 - pypy3-test-instrumentation-falcon-{0,1,2,3,4} + pypy3-test-instrumentation-falcon-{1,2,3,4} lint-instrumentation-falcon ; opentelemetry-instrumentation-fastapi - py3{9,10,11,12,13,14}-test-instrumentation-fastapi + py3{10,11,12,13,14}-test-instrumentation-fastapi pypy3-test-instrumentation-fastapi lint-instrumentation-fastapi @@ -169,12 +165,12 @@ envlist = ; 1: Flask ==2.2.0 Werkzeug <3.0.0 ; 2: Flask >=3.0.0 Werkzeug >=3.0.0 ; 3: Flask >=3.1.0 Werkzeug >=3.1.0 - py3{9,10,11,12,13,14}-test-instrumentation-flask-{0,1,2,3} + py3{10,11,12,13,14}-test-instrumentation-flask-{0,1,2,3} pypy3-test-instrumentation-flask-{0,1} lint-instrumentation-flask ; opentelemetry-instrumentation-urllib - py3{9,10,11,12,13,14}-test-instrumentation-urllib + py3{10,11,12,13,14}-test-instrumentation-urllib pypy3-test-instrumentation-urllib lint-instrumentation-urllib @@ -184,40 +180,40 @@ envlist = ; 0: urllib3 >=1.0.0,<2.0.0 ; 1: urllib3 >=2.0.0,<3.0.0 ; TODO #4200 Add py314 testing after replacing httpretty -- problem with https tests in 3.14 - py3{9,10,11,12,13}-test-instrumentation-urllib3-{0,1} + py3{10,11,12,13}-test-instrumentation-urllib3-{0,1} pypy3-test-instrumentation-urllib3-{0,1} lint-instrumentation-urllib3 ; opentelemetry-instrumentation-requests - py3{9,10,11,12,13,14}-test-instrumentation-requests + py3{10,11,12,13,14}-test-instrumentation-requests ;pypy3-test-instrumentation-requests lint-instrumentation-requests ; opentelemetry-instrumentation-starlette - py3{9,10,11,12,13,14}-test-instrumentation-starlette-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-starlette-{oldest,latest} pypy3-test-instrumentation-starlette-{oldest,latest} lint-instrumentation-starlette ; opentelemetry-instrumentation-jinja2 - py3{9,10,11,12,13,14}-test-instrumentation-jinja2 + py3{10,11,12,13,14}-test-instrumentation-jinja2 pypy3-test-instrumentation-jinja2 lint-instrumentation-jinja2 ; opentelemetry-instrumentation-logging - py3{9,10,11,12,13,14}-test-instrumentation-logging + py3{10,11,12,13,14}-test-instrumentation-logging pypy3-test-instrumentation-logging lint-instrumentation-logging benchmark-instrumentation-logging ; opentelemetry-exporter-richconsole - py3{9,10,11,12,13,14}-test-exporter-richconsole + py3{10,11,12,13,14}-test-exporter-richconsole pypy3-test-exporter-richconsole lint-exporter-richconsole ; opentelemetry-exporter-prometheus-remote-write - py3{9,10,11,12,13,14}-test-exporter-prometheus-remote-write + py3{10,11,12,13,14}-test-exporter-prometheus-remote-write # excluded from pypy3 due to missing wheel - pypy310-test-exporter-prometheus-remote-write + pypy3-test-exporter-prometheus-remote-write lint-exporter-prometheus-remote-write ; opentelemetry-instrumentation-mysql @@ -225,12 +221,12 @@ envlist = ; below mean these dependencies are being used: ; 0: mysql-connector-python >=8.0.0,<9.0.0 ; 1: mysql-connector-python ~=9.0.0 - py3{9,10,11,12,13,14}-test-instrumentation-mysql-{0,1} + py3{10,11,12,13,14}-test-instrumentation-mysql-{0,1} pypy3-test-instrumentation-mysql-{0,1} lint-instrumentation-mysql ; opentelemetry-instrumentation-mysqlclient - py3{9,10,11,12,13,14}-test-instrumentation-mysqlclient + py3{10,11,12,13,14}-test-instrumentation-mysqlclient pypy3-test-instrumentation-mysqlclient ; prerequisite: follow the instructions here ; https://github.com/PyMySQL/mysqlclient#install @@ -238,13 +234,13 @@ envlist = lint-instrumentation-mysqlclient ; opentelemetry-instrumentation-psycopg2 - py3{9,10,11,12,13,14}-test-instrumentation-psycopg2 - py3{9,10,11,12,13,14}-test-instrumentation-psycopg2-binary + py3{10,11,12,13,14}-test-instrumentation-psycopg2 + py3{10,11,12,13,14}-test-instrumentation-psycopg2-binary ; ext-psycopg2 intentionally excluded from pypy3 lint-instrumentation-psycopg2 ; opentelemetry-instrumentation-psycopg - py3{9,10,11,12,13,14}-test-instrumentation-psycopg + py3{10,11,12,13,14}-test-instrumentation-psycopg pypy3-test-instrumentation-psycopg lint-instrumentation-psycopg @@ -256,48 +252,48 @@ envlist = ; 2: pymemcache >3.0.0,<3.4.2 ; 3: pymemcache ==3.4.2 ; 4: pymemcache ==4.0.0 - py3{9,10,11,12,13,14}-test-instrumentation-pymemcache-{0,1,2,3,4} + py3{10,11,12,13,14}-test-instrumentation-pymemcache-{0,1,2,3,4} pypy3-test-instrumentation-pymemcache-{0,1,2,3,4} lint-instrumentation-pymemcache ; opentelemetry-instrumentation-pymongo - py3{9,10,11,12,13,14}-test-instrumentation-pymongo + py3{10,11,12,13,14}-test-instrumentation-pymongo pypy3-test-instrumentation-pymongo lint-instrumentation-pymongo ; opentelemetry-instrumentation-pymysql - py3{9,10,11,12,13,14}-test-instrumentation-pymysql + py3{10,11,12,13,14}-test-instrumentation-pymysql pypy3-test-instrumentation-pymysql lint-instrumentation-pymysql ; opentelemetry-instrumentation-pymssql - py3{9,10,11,12,13,14}-test-instrumentation-pymssql + py3{10,11,12,13,14}-test-instrumentation-pymssql ; pymssql has no support for pypy: see https://github.com/pymssql/pymssql/pull/517 ; pypy3-test-instrumentation-pymssql lint-instrumentation-pymssql ; opentelemetry-instrumentation-pyramid - py3{9,10,11,12,13,14}-test-instrumentation-pyramid + py3{10,11,12,13,14}-test-instrumentation-pyramid pypy3-test-instrumentation-pyramid lint-instrumentation-pyramid ; opentelemetry-instrumentation-asgi - py3{9,10,11,12,13,14}-test-instrumentation-asgi + py3{10,11,12,13,14}-test-instrumentation-asgi pypy3-test-instrumentation-asgi lint-instrumentation-asgi ; opentelemetry-instrumentation-asyncpg - py3{9,10,11,12,13,14}-test-instrumentation-asyncpg-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-asyncpg-{wrapt1,wrapt2} ; ext-asyncpg intentionally excluded from pypy3 lint-instrumentation-asyncpg ; opentelemetry-instrumentation-sqlite3 - py3{9,10,11,12,13,14}-test-instrumentation-sqlite3 + py3{10,11,12,13,14}-test-instrumentation-sqlite3 pypy3-test-instrumentation-sqlite3 lint-instrumentation-sqlite3 ; opentelemetry-instrumentation-wsgi - py3{9,10,11,12,13,14}-test-instrumentation-wsgi + py3{10,11,12,13,14}-test-instrumentation-wsgi pypy3-test-instrumentation-wsgi lint-instrumentation-wsgi @@ -307,53 +303,53 @@ envlist = ; 0: grpcio==1.62.0 ; 1: grpcio==1.75.1 ; TODO #4201 simplify tests-requirements here to use latest|oldest testing pattern - py3{9,10,11,12}-test-instrumentation-grpc-{0,1}-{wrapt1,wrapt2} + py3{10,11,12}-test-instrumentation-grpc-{0,1}-{wrapt1,wrapt2} py3{13,14}-test-instrumentation-grpc-1-{wrapt1,wrapt2} lint-instrumentation-grpc ; opentelemetry-instrumentation-sqlalchemy ; The numbers at the end of the environment names ; below mean these dependencies are being used: - ; 0: sqlalchemy>=1.1,<1.2 + ; 0: sqlalchemy>=1.1,<1.2 - TODO: drop test-requirements-0.txt and update to >=1.4,<2.0 once 1.1 support is removed ; 1: sqlalchemy~=1.4 aiosqlite ; 2: sqlalchemy~=2.0.0 - py3{9,10,11,12,13}-test-instrumentation-sqlalchemy-{1,2} + py3{10,11,12,13}-test-instrumentation-sqlalchemy-{1,2} py314-test-instrumentation-sqlalchemy-2 - pypy3-test-instrumentation-sqlalchemy-{0,1,2} + pypy3-test-instrumentation-sqlalchemy-{1,2} lint-instrumentation-sqlalchemy ; opentelemetry-instrumentation-redis - py3{9,10,11,12,13,14}-test-instrumentation-redis + py3{10,11,12,13,14}-test-instrumentation-redis pypy3-test-instrumentation-redis lint-instrumentation-redis ; opentelemetry-instrumentation-remoulade - py3{9,10,11,12,13,14}-test-instrumentation-remoulade + py3{10,11,12,13,14}-test-instrumentation-remoulade ; instrumentation-remoulade intentionally excluded from pypy3 lint-instrumentation-remoulade ; opentelemetry-instrumentation-celery - py3{9,10,11,12,13,14}-test-instrumentation-celery + py3{10,11,12,13,14}-test-instrumentation-celery pypy3-test-instrumentation-celery lint-instrumentation-celery ; opentelemetry-instrumentation-system-metrics - py3{9,10,11,12,13,14}-test-instrumentation-system-metrics + py3{10,11,12,13,14}-test-instrumentation-system-metrics pypy3-test-instrumentation-system-metrics lint-instrumentation-system-metrics ; opentelemetry-instrumentation-threading - py3{9,10,11,12,13,14}-test-instrumentation-threading + py3{10,11,12,13,14}-test-instrumentation-threading pypy3-test-instrumentation-threading lint-instrumentation-threading ; opentelemetry-instrumentation-tornado - py3{9,10,11,12,13,14}-test-instrumentation-tornado + py3{10,11,12,13,14}-test-instrumentation-tornado pypy3-test-instrumentation-tornado lint-instrumentation-tornado ; opentelemetry-instrumentation-tortoiseorm - py3{9,10,11,12,13,14}-test-instrumentation-tortoiseorm + py3{10,11,12,13,14}-test-instrumentation-tortoiseorm pypy3-test-instrumentation-tortoiseorm lint-instrumentation-tortoiseorm @@ -362,33 +358,33 @@ envlist = ; below mean these dependencies are being used: ; 0: httpx>=0.18.0,<0.19.0 respx~=0.17.0 ; 1: httpx>=0.19.0 respx~=0.20.1 - py3{9,10,11,12}-test-instrumentation-httpx-{0,1}-{wrapt1,wrapt2} + py3{10,11,12}-test-instrumentation-httpx-{0,1}-{wrapt1,wrapt2} py3{13,14}-test-instrumentation-httpx-1-{wrapt1,wrapt2} pypy3-test-instrumentation-httpx-{0,1}-wrapt2 lint-instrumentation-httpx ; opentelemetry-util-http - py3{9,10,11,12,13,14}-test-util-http + py3{10,11,12,13,14}-test-util-http pypy3-test-util-http lint-util-http ; opentelemetry-exporter-credential-provider-gcp - py3{9,10,11,12,13,14}-test-exporter-credential-provider-gcp + py3{10,11,12,13,14}-test-exporter-credential-provider-gcp lint-exporter-credential-provider-gcp ; opentelemetry-util-genai - py3{9,10,11,12,13,14}-test-util-genai + py3{10,11,12,13,14}-test-util-genai pypy3-test-util-genai lint-util-genai ; opentelemetry-propagator-aws-xray - py3{9,10,11,12,13,14}-test-propagator-aws-xray-{0,1} + py3{10,11,12,13,14}-test-propagator-aws-xray-{0,1} pypy3-test-propagator-aws-xray-{0,1} lint-propagator-aws-xray benchmark-propagator-aws-xray ; opentelemetry-propagator-ot-trace - py3{9,10,11,12,13,14}-test-propagator-ot-trace + py3{10,11,12,13,14}-test-propagator-ot-trace pypy3-test-propagator-ot-trace lint-propagator-ot-trace @@ -397,7 +393,7 @@ envlist = ; below mean these dependencies are being used: ; 0: pika>=0.12.0,<1.0.0 ; 1: pika>=1.0.0 - py3{9,10,11,12,13,14}-test-instrumentation-sio-pika-{0,1}-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-sio-pika-{0,1}-{wrapt1,wrapt2} pypy3-test-instrumentation-sio-pika-{0,1}-wrapt2 lint-instrumentation-sio-pika @@ -408,43 +404,43 @@ envlist = ; 1: aio_pika==8.3.0 ; 2: aio_pika==9.0.5 ; 3: aio_pika==9.4.1 - py3{9,10,11,12,13,14}-test-instrumentation-aio-pika-{0,1,2,3} + py3{10,11,12,13,14}-test-instrumentation-aio-pika-{0,1,2,3} pypy3-test-instrumentation-aio-pika-{0,1,2,3} lint-instrumentation-aio-pika ; opentelemetry-instrumentation-aiokafka - py3{9,10,11,12,13,14}-test-instrumentation-aiokafka + py3{10,11,12,13,14}-test-instrumentation-aiokafka pypy3-test-instrumentation-aiokafka lint-instrumentation-aiokafka ; opentelemetry-instrumentation-kafka-python - py3{9,10,11}-test-instrumentation-kafka-python - py3{9,10,11,12,13,14}-test-instrumentation-kafka-pythonng + py3{10,11}-test-instrumentation-kafka-python + py3{10,11,12,13,14}-test-instrumentation-kafka-pythonng pypy3-test-instrumentation-kafka-python pypy3-test-instrumentation-kafka-pythonng lint-instrumentation-kafka-python ; opentelemetry-instrumentation-confluent-kafka - py3{9,10,11,12,13,14}-test-instrumentation-confluent-kafka + py3{10,11,12,13,14}-test-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka ; opentelemetry-instrumentation-asyncio - py3{9,10,11,12,13,14}-test-instrumentation-asyncio + py3{10,11,12,13,14}-test-instrumentation-asyncio lint-instrumentation-asyncio ; opentelemetry-instrumentation-cassandra - py3{9,10,11,12,13,14}-test-instrumentation-cassandra-{driver,scylla} + py3{10,11,12,13,14}-test-instrumentation-cassandra-{driver,scylla} pypy3-test-instrumentation-cassandra-scylla lint-instrumentation-cassandra ; opentelemetry-processor-baggage - py3{9,10,11,12,13,14}-test-processor-baggage + py3{10,11,12,13,14}-test-processor-baggage pypy3-test-processor-baggage ; requires snappy headers to be available on the system lint-processor-baggage ; opentelemetry-opamp-client - py3{9,10,11,12,13,14}-test-opamp-client-{latest,lowest} + py3{10,11,12,13,14}-test-opamp-client-{latest,lowest} ; https://github.com/kevin1024/vcrpy/pull/775#issuecomment-1847849962 ; pypy3-test-opamp-client lint-opamp-client @@ -515,7 +511,6 @@ deps = asgi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt celery: {[testenv]test_deps} - py3{9}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt py3{10,11,12,13,14}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt pypy3-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt lint-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -617,13 +612,10 @@ deps = lint-instrumentation-dbapi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt2.txt django: {[testenv]test_deps} - py3{9}-test-instrumentation-django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt - py3{9}-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - py3{9}-test-instrumentation-django-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt - py3{10,11,12}-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - py3{10,11,12,13,14}-test-instrumentation-django-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt - pypy3-test-instrumentation-django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt - pypy3-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt + django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt + django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt + django-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt + django-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt lint-instrumentation-django: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt fastapi: {[testenv]test_deps} @@ -649,7 +641,6 @@ deps = pymongo: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt psycopg: {[testenv]test_deps} - py3{9}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt py3{10,11,12,13,14}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt pypy3-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt lint-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt diff --git a/util/opentelemetry-util-genai/pyproject.toml b/util/opentelemetry-util-genai/pyproject.toml index f8705369c2e..be3ba572385 100644 --- a/util/opentelemetry-util-genai/pyproject.toml +++ b/util/opentelemetry-util-genai/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry GenAI Utils" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/util/opentelemetry-util-http/pyproject.toml b/util/opentelemetry-util-http/pyproject.toml index 87d963cf01c..48170a2f319 100644 --- a/util/opentelemetry-util-http/pyproject.toml +++ b/util/opentelemetry-util-http/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Web util for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", From baffc8c3047209c5018084e050bd1c2830a90aaf Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Tue, 14 Apr 2026 10:20:41 +0200 Subject: [PATCH 64/78] Add AGENTS.md with project structure and commands (#4233) * Add CLAUDE.md with project structure and commands * Add AGENTS.md symlink to CLAUDE.md * Move guidance to AGENTS.md and address review feedback - Move main content from CLAUDE.md to AGENTS.md so all AI agents (not only Claude) pick up the guidance; CLAUDE.md now just references it via `@AGENTS.md`. - Add general rules, PR scoping, and `Assisted-by:` commit trailer guidance (inspired by the Collector's AGENTS.md). - Clarify that only instrumentation packages live under `src/opentelemetry/instrumentation/{name}/`; other package types use their own namespace. --------- Co-authored-by: Riccardo Magliocchetti --- AGENTS.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + 2 files changed, 70 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..7467033607f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,69 @@ +# OpenTelemetry Python Contrib + +This file is here to steer AI assisted PRs towards being high quality and valuable contributions +that do not create excessive maintainer burden. + +Monorepo with 50+ OpenTelemetry instrumentation packages for Python. + +## General Rules and Guidelines + +The most important rule is not to post comments on issues or PRs that are AI-generated. Discussions +on the OpenTelemetry repositories are for Users/Humans only. + +Follow the PR scoping guidance in [CONTRIBUTING.md](CONTRIBUTING.md). Keep AI-assisted PRs tightly +isolated to the requested change and never include unrelated cleanup or opportunistic improvements +unless they are strictly necessary for correctness. + +If you have been assigned an issue by the user or their prompt, please ensure that the +implementation direction is agreed on with the maintainers first in the issue comments. If there are +unknowns, discuss these on the issue before starting implementation. Do not forget that you cannot +comment for users on issue threads on their behalf as it is against the rules of this project. + +## Structure + +- `instrumentation/` - instrumentation packages (Flask, Django, FastAPI, gRPC, databases, etc.) +- `instrumentation-genai/` - GenAI instrumentations (Anthropic, Vertex AI, LangChain, etc.) +- `util/` - shared utilities (`util-http`, `util-genai`) +- `exporter/` - custom exporters +- `propagator/` - context propagators + +Instrumentation packages live under `src/opentelemetry/instrumentation/{name}/` with their own +`pyproject.toml` and `tests/`. Other package types follow the equivalent layout under their own +namespace (e.g. `src/opentelemetry/util/{name}/`, `src/opentelemetry/exporter/{name}/`). + +## Commands + +```sh +# Install all packages and dev tools +uv sync --frozen --all-packages + +# Lint (runs ruff via pre-commit) +uv run pre-commit run ruff --all-files + +# Test a specific package (append -0, -1, etc. for version variants) +uv run tox -e py312-test-instrumentation-flask-0 + +# Type check +uv run tox -e typecheck +``` + +## Guidelines + +- Each package has its own `pyproject.toml` with version, dependencies, and entry points. +- The monorepo uses `uv` workspaces. +- `tox.ini` defines the test matrix - check it for available test environments. +- Do not add `type: ignore` comments. If a type error arises, solve it properly or write a follow-up plan to address it in another PR. +- Whenever applicable, all code changes should have tests that actually validate the changes. + +## Commit formatting + +We appreciate it if users disclose the use of AI tools when the significant part of a commit is +taken from a tool without changes. When making a commit this should be disclosed through an +`Assisted-by:` commit message trailer. + +Examples: + +``` +Assisted-by: ChatGPT 5.2 +Assisted-by: Claude Opus 4.6 +``` diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..43c994c2d36 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md From afbe6fde6c5764fba355c4ab70ec5d1af28d6165 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 14 Apr 2026 14:48:01 +0200 Subject: [PATCH 65/78] scripts: drop update_sha (#4430) It's buggy and unused. --- scripts/update_sha.py | 66 ------------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 scripts/update_sha.py diff --git a/scripts/update_sha.py b/scripts/update_sha.py deleted file mode 100644 index c63b9eda9bf..00000000000 --- a/scripts/update_sha.py +++ /dev/null @@ -1,66 +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. - -# pylint: disable=import-error,unspecified-encoding - -import argparse - -import requests -from ruamel.yaml import YAML - -API_URL = ( - "https://api.github.com/repos/open-telemetry/opentelemetry-python/commits/" -) -workflow_files = [ - ".github/workflows/test_0.yml" - ".github/workflows/test_1.yml" - ".github/workflows/misc_0.yml" - ".github/workflows/lint_0.yml" -] - - -def get_sha(branch): - url = API_URL + branch - response = requests.get(url, timeout=15) - response.raise_for_status() - return response.json()["sha"] - - -def update_sha(sha): - yaml = YAML() - yaml.preserve_quotes = True - for workflow_file in workflow_files: - with open(workflow_file, "r") as file: - workflow = yaml.load(file) - workflow["env"]["CORE_REPO_SHA"] = sha - with open(workflow_file, "w") as file: - yaml.dump(workflow, file) - - -def main(): - args = parse_args() - sha = get_sha(args.branch) - update_sha(sha) - - -def parse_args(): - parser = argparse.ArgumentParser( - description="Updates the SHA in the workflow file" - ) - parser.add_argument("-b", "--branch", help="branch to use") - return parser.parse_args() - - -if __name__ == "__main__": - main() From dcf86d00fc4c9368debe8e350efce4455fccbe8f Mon Sep 17 00:00:00 2001 From: Sri Kaaviya <107148069+srikaaviya@users.noreply.github.com> Date: Tue, 14 Apr 2026 07:56:58 -0700 Subject: [PATCH 66/78] Fix pylint false positives for ThreadPoolExecutor (#4244) * Bump pylint to 4.0.5 to fix Python 3.14 concurrent.futures false positives * Fix too-many-positional-arguments pylint failures - Add max-positional-arguments=10, Add pylint: disable=too-many-positional-arguments to functions that legitimately exceed the limit * Bump max-positional-arguments to 12 and remove unnecessary disable comments * Address review comments: fix CHANGELOG, remove stale pylintrc comment, add openai-agents disable * Fix formatting: restore blank line in CHANGELOG and remove extra blank line in .pylintrc * Update processor.py * Update test_botocore_bedrock.py --------- Co-authored-by: Riccardo Magliocchetti --- .pylintrc | 7 +++---- CHANGELOG.md | 5 +++++ dev-requirements.txt | 2 +- .../instrumentation/openai_agents/span_processor.py | 1 + .../opentelemetry/instrumentation/asgi/__init__.py | 2 +- .../tests/test_asyncio_run_coroutine_threadsafe.py | 4 +--- .../tests/test_botocore_bedrock.py | 11 ----------- .../tests/test_threading.py | 2 +- .../opentelemetry/instrumentation/urllib3/__init__.py | 2 +- .../src/opentelemetry/processor/baggage/processor.py | 2 +- .../sdk/extension/aws/trace/sampler/_sampling_rule.py | 2 +- .../util/genai/_upload/completion_hook.py | 2 +- 12 files changed, 17 insertions(+), 25 deletions(-) diff --git a/.pylintrc b/.pylintrc index 17f53f20985..d3a4723112e 100644 --- a/.pylintrc +++ b/.pylintrc @@ -37,10 +37,6 @@ persistent=yes # Specify a configuration file. #rcfile= -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no @@ -463,6 +459,9 @@ valid-metaclass-classmethod-first-arg=cls # Maximum number of arguments for function / method. max-args=5 +# Maximum number of positional arguments for function / method. +max-positional-arguments=12 + # Maximum number of attributes for a class (see R0902). max-attributes=7 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dca6b771e9..8818f8b0700 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Bump `pylint` to `4.0.5` + ([#4244](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4244)) + ### Breaking changes - Drop Python 3.9 support diff --git a/dev-requirements.txt b/dev-requirements.txt index 29325a6d352..28b7f814871 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,4 +1,4 @@ -pylint==3.0.2 +pylint==4.0.5 httpretty==1.1.4 pyright==v1.1.404 sphinx==7.1.2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py index 74be6637010..55539a4931c 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py @@ -426,6 +426,7 @@ def get_span_name( class GenAISemanticProcessor(TracingProcessor): """Trace processor adding GenAI semantic convention attributes with metrics.""" + # pylint: disable=too-many-positional-arguments def __init__( self, tracer: Optional[Tracer] = None, diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index e28315f502e..8e7106010fd 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -586,7 +586,7 @@ class OpenTelemetryMiddleware: exclude_spans: Optionally exclude HTTP `send` and/or `receive` spans from the trace. """ - # pylint: disable=too-many-branches + # pylint: disable=too-many-branches,too-many-positional-arguments def __init__( self, app, diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_run_coroutine_threadsafe.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_run_coroutine_threadsafe.py index d612076dbf9..fdf4bcb353d 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_run_coroutine_threadsafe.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_run_coroutine_threadsafe.py @@ -13,9 +13,7 @@ # limitations under the License. import asyncio import threading -from concurrent.futures import ( # pylint: disable=no-name-in-module; TODO #4199 - ThreadPoolExecutor, -) +from concurrent.futures import ThreadPoolExecutor from unittest.mock import patch # pylint: disable=no-name-in-module diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py index ef0146314f1..bf8a2ac2429 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py @@ -1487,7 +1487,6 @@ def test_invoke_model_with_content( finish_reason = "length" else: pytest.xfail("model family not handled: {model_family}") - return assert_message_in_logs(logs[0], "gen_ai.user.message", user_content, span) @@ -1628,7 +1627,6 @@ def test_invoke_model_with_content_different_events( choice_content = [{"type": "text", "text": "This is a test"}] else: pytest.xfail("llm_model_value not handled: {llm_model_value}") - return body = get_invoke_model_body( llm_model_value, @@ -2070,7 +2068,6 @@ def test_invoke_model_with_content_tool_call( llm_model_config = AnthropicClaudeModel else: pytest.xfail("model family not handled: {model_family}") - return invoke_model_tool_call( span_exporter, @@ -2156,7 +2153,6 @@ def test_invoke_model_no_content( finish_reason = "length" else: pytest.xfail("model family not handled: {model_family}") - return choice_body = { "index": 0, @@ -2190,7 +2186,6 @@ def test_invoke_model_no_content_different_events( finish_reason = "end_turn" else: pytest.xfail("llm_model_value not handled: {llm_model_value}") - return body = get_invoke_model_body( llm_model_value, @@ -2246,7 +2241,6 @@ def test_invoke_model_no_content_tool_call( llm_model_config = AnthropicClaudeModel else: pytest.xfail("model family not handled: {model_family}") - return invoke_model_tool_call( span_exporter, @@ -2401,7 +2395,6 @@ def test_invoke_model_with_response_stream_with_content( } else: pytest.xfail("model family not handled: {model_family}") - return choice_body = { "index": 0, @@ -2437,7 +2430,6 @@ def test_invoke_model_with_response_stream_with_content_different_events( choice_content = [{"text": "This is a test", "type": "text"}] else: pytest.xfail("llm_model_value not handled: {llm_model_value}") - return max_tokens = 10 body = get_invoke_model_body( @@ -2672,7 +2664,6 @@ def test_invoke_model_with_response_stream_with_content_tool_call( llm_model_config = AnthropicClaudeModel else: pytest.xfail("model family not handled: {model_family}") - return invoke_model_with_response_stream_tool_call( span_exporter, @@ -2801,7 +2792,6 @@ def test_invoke_model_with_response_stream_no_content_different_events( finish_reason = "end_turn" else: pytest.xfail("llm_model_value not handled: {llm_model_value}") - return max_tokens = 10 body = get_invoke_model_body( @@ -2864,7 +2854,6 @@ def test_invoke_model_with_response_stream_no_content_tool_call( llm_model_config = AnthropicClaudeModel else: pytest.xfail("model family not handled: {model_family}") - return invoke_model_with_response_stream_tool_call( span_exporter, diff --git a/instrumentation/opentelemetry-instrumentation-threading/tests/test_threading.py b/instrumentation/opentelemetry-instrumentation-threading/tests/test_threading.py index 3a06969b26c..e0f1c63fbbf 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/tests/test_threading.py +++ b/instrumentation/opentelemetry-instrumentation-threading/tests/test_threading.py @@ -15,7 +15,7 @@ from __future__ import annotations import threading -from concurrent.futures import ( # pylint: disable=no-name-in-module; TODO #4199 +from concurrent.futures import ( Future, ThreadPoolExecutor, ) diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index 5c833a4720b..0c92b6b6b80 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -424,7 +424,7 @@ def _get_span_name(method: str) -> str: return method -# pylint: disable=too-many-locals +# pylint: disable=too-many-locals,too-many-positional-arguments def _instrument( tracer: Tracer, duration_histogram_old: Histogram, diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py index 7e09e591e05..d28cc1e68d6 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py @@ -23,7 +23,7 @@ BaggageKeyPredicateT = Callable[[str], bool] # A BaggageKeyPredicate that always returns True, allowing all baggage keys to be added to spans -ALLOW_ALL_BAGGAGE_KEYS: BaggageKeyPredicateT = lambda _: True # noqa: E731 +ALLOW_ALL_BAGGAGE_KEYS: BaggageKeyPredicateT = lambda _: True # noqa: E731 # pylint:disable=invalid-name class BaggageSpanProcessor(SpanProcessor): diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/sampler/_sampling_rule.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/sampler/_sampling_rule.py index fd99b2a87f9..0ee531017ef 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/sampler/_sampling_rule.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/sampler/_sampling_rule.py @@ -20,7 +20,7 @@ # Disable snake_case naming style so this class can match the sampling rules response from X-Ray -# pylint: disable=invalid-name +# pylint: disable=invalid-name,too-many-positional-arguments class _SamplingRule: def __init__( self, diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py index 79ebd3a1708..f2b9254f493 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py @@ -22,7 +22,7 @@ import posixpath import threading from collections import OrderedDict -from concurrent.futures import ( # pylint: disable=no-name-in-module; TODO #4199 +from concurrent.futures import ( Future, ThreadPoolExecutor, ) From 34bfc28680e4e61b9904d151fa5955cad6c5644d Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 15 Apr 2026 01:12:55 -0700 Subject: [PATCH 67/78] feat(util-genai): refactor and make API smaller and more user-friendly (#4391) * Refactor public API on GenAI utils * more lint * review feedback * update tests to use named params * address some of the comments * up * fix failing checks and clean up imports * lint * lint * fix lint * replace @deprecated with docstring info to avoid warnings for users * up * common code for context manager --- .gitignore | 5 + instrumentation-genai/AGENTS.md | 41 ++ instrumentation-genai/CLAUDE.md | 1 + .../instrumentation/anthropic/patch.py | 5 +- .../instrumentation/anthropic/wrappers.py | 2 +- .../langchain/callback_handler.py | 10 +- .../pyproject.toml | 6 +- .../tests/requirements.latest.txt | 1 + .../tests/requirements.oldest.txt | 7 +- .../pyproject.toml | 2 +- .../instrumentation/openai_v2/patch.py | 2 +- .../openai_v2/response_wrappers.py | 5 +- .../instrumentation/openai_v2/utils.py | 2 +- util/opentelemetry-util-genai/AGENTS.md | 80 ++++ util/opentelemetry-util-genai/CHANGELOG.md | 6 +- util/opentelemetry-util-genai/CLAUDE.md | 1 + util/opentelemetry-util-genai/pyproject.toml | 1 + .../util/genai/_embedding_invocation.py | 124 +++++ .../util/genai/_inference_invocation.py | 358 ++++++++++++++ .../opentelemetry/util/genai/_invocation.py | 140 ++++++ .../util/genai/_tool_invocation.py | 96 ++++ .../util/genai/_workflow_invocation.py | 115 +++++ .../src/opentelemetry/util/genai/handler.py | 447 ++++++++---------- .../opentelemetry/util/genai/invocation.py | 47 ++ .../src/opentelemetry/util/genai/metrics.py | 77 +-- .../opentelemetry/util/genai/span_utils.py | 417 ---------------- .../src/opentelemetry/util/genai/types.py | 235 ++------- .../tests/test_handler_metrics.py | 32 +- .../tests/test_handler_workflow.py | 177 ++----- .../tests/test_toolcall.py | 42 +- .../tests/test_utils.py | 249 +++++----- .../tests/test_utils_events.py | 108 ++--- .../tests/test_workflow_invocation.py | 75 ++- 33 files changed, 1573 insertions(+), 1343 deletions(-) create mode 100644 instrumentation-genai/AGENTS.md create mode 120000 instrumentation-genai/CLAUDE.md create mode 100644 util/opentelemetry-util-genai/AGENTS.md create mode 120000 util/opentelemetry-util-genai/CLAUDE.md create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_workflow_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/invocation.py delete mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py diff --git a/.gitignore b/.gitignore index 1c32b4446a9..6c3e08c1176 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,8 @@ target # Benchmark result files *-benchmark.json + +# opentelemetry-admin jobs +opentelemetry-admin-jobs.txt + +.claude/settings.local.json diff --git a/instrumentation-genai/AGENTS.md b/instrumentation-genai/AGENTS.md new file mode 100644 index 00000000000..6e8dd1eca90 --- /dev/null +++ b/instrumentation-genai/AGENTS.md @@ -0,0 +1,41 @@ +# GenAI Instrumentation — Agent and Contributor Guidelines + +Instrumentation packages here wrap specific libraries (OpenAI, Anthropic, etc.) and bridge +them to the shared telemetry layer in `util/opentelemetry-util-genai`. + +## 1. Instrumentation Layer Boundary + +Do not call OpenTelemetry APIs (`tracer`, `meter`, `span`, event APIs) directly. +Always go through `TelemetryHandler` and the invocation objects it returns. + +This layer is responsible only for: + +- Patching the library +- Parsing library-specific input/output into invocation fields + +Everything else (span creation, metric recording, event emission, context propagation) +belongs in `util/opentelemetry-util-genai`. + +## 2. Invocation Pattern + +Use `start_*()` and control span lifetime manually: + +```python +invocation = handler.start_inference(provider, request_model, server_address=..., server_port=...) +invocation.temperature = ... +try: + response = client.call(...) + invocation.response_model_name = response.model + invocation.finish_reasons = response.finish_reasons + invocation.stop() +except Exception as exc: + invocation.fail(exc) + raise +``` + +## 3. Exception Handling + +- Do not add `raise {Error}` statements in instrumentation/telemetry code — validation belongs in + tests and callers, not in the instrumentation layer. +- When catching exceptions from the underlying library to record telemetry, always re-raise + the original exception unmodified. diff --git a/instrumentation-genai/CLAUDE.md b/instrumentation-genai/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/instrumentation-genai/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py index 4dc8b55d388..845e10de3f9 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py @@ -26,7 +26,10 @@ gen_ai_attributes as GenAIAttributes, ) from opentelemetry.util.genai.handler import TelemetryHandler -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import ( + Error, + LLMInvocation, # TODO: migrate to InferenceInvocation +) from opentelemetry.util.genai.utils import ( should_capture_content_on_spans_in_experimental_mode, ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py index 52e2e68582b..1a9d5319a5b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py @@ -31,7 +31,7 @@ from opentelemetry.util.genai.handler import TelemetryHandler from opentelemetry.util.genai.types import ( Error, - LLMInvocation, + LLMInvocation, # TODO: migrate to InferenceInvocation ) from .messages_extractors import set_invocation_response_attributes diff --git a/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py b/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py index d694857da44..5235af3c7f1 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py +++ b/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py @@ -28,7 +28,7 @@ from opentelemetry.util.genai.types import ( Error, InputMessage, - LLMInvocation, + LLMInvocation, # TODO: migrate to InferenceInvocation MessagePart, OutputMessage, Text, @@ -158,7 +158,7 @@ def on_chat_model_start( self._invocation_manager.add_invocation_state( run_id=run_id, parent_run_id=parent_run_id, - invocation=llm_invocation, + invocation=llm_invocation, # pyright: ignore[reportArgumentType] ) def on_llm_end( @@ -171,7 +171,8 @@ def on_llm_end( ) -> None: llm_invocation = self._invocation_manager.get_invocation(run_id=run_id) if llm_invocation is None or not isinstance( - llm_invocation, LLMInvocation + llm_invocation, + LLMInvocation, ): # If the invocation does not exist, we cannot set attributes or end it return @@ -262,7 +263,8 @@ def on_llm_error( ) -> None: llm_invocation = self._invocation_manager.get_invocation(run_id=run_id) if llm_invocation is None or not isinstance( - llm_invocation, LLMInvocation + llm_invocation, + LLMInvocation, ): # If the invocation does not exist, we cannot set attributes or end it return diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml index e87c28d879a..fe7bfa6d82d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml @@ -25,10 +25,10 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-api >= 1.37", + "opentelemetry-api >= 1.39", "opentelemetry-instrumentation >= 0.58b0", - "opentelemetry-semantic-conventions >= 0.58b0", - "opentelemetry-util-genai" + "opentelemetry-semantic-conventions >= 0.60b0", + "opentelemetry-util-genai >= 0.4b0.dev" ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.latest.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.latest.txt index e224e4349b6..2bd34ba349f 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.latest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.latest.txt @@ -50,4 +50,5 @@ grpcio>=1.60.0; implementation_name != "pypy" grpcio<1.60.0; implementation_name == "pypy" -e opentelemetry-instrumentation +-e util/opentelemetry-util-genai -e instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt index 2e935a63b6a..537c2b9ba22 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt @@ -26,10 +26,11 @@ pytest-asyncio==0.21.0 wrapt==1.16.0 opentelemetry-exporter-otlp-proto-grpc~=1.30 opentelemetry-exporter-otlp-proto-http~=1.30 -opentelemetry-api==1.37 # when updating, also update in pyproject.toml -opentelemetry-sdk==1.37 # when updating, also update in pyproject.toml -opentelemetry-semantic-conventions==0.58b0 # when updating, also update in pyproject.toml +opentelemetry-api==1.39 # when updating, also update in pyproject.toml +opentelemetry-sdk==1.39 # when updating, also update in pyproject.toml +opentelemetry-semantic-conventions==0.60b0 # when updating, also update in pyproject.toml grpcio>=1.60.0; implementation_name != "pypy" grpcio<1.60.0; implementation_name == "pypy" +-e util/opentelemetry-util-genai -e instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index 807d5bf9981..73bf8d3c57a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "opentelemetry-api ~= 1.39", "opentelemetry-instrumentation ~= 0.60b0", "opentelemetry-semantic-conventions ~= 0.60b0", - "opentelemetry-util-genai", + "opentelemetry-util-genai >= 0.4b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index 996c91c04df..30f74cfab11 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -36,7 +36,7 @@ from opentelemetry.util.genai.types import ( ContentCapturingMode, Error, - LLMInvocation, + LLMInvocation, # pylint: disable=no-name-in-module # TODO: migrate to InferenceInvocation OutputMessage, Text, ToolCallRequest, diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py index ce3375b8d5f..402e5c84c24 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py @@ -8,7 +8,10 @@ from typing import TYPE_CHECKING, Callable, Generator, Generic, TypeVar from opentelemetry.util.genai.handler import TelemetryHandler -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import ( + Error, + LLMInvocation, # pylint: disable=no-name-in-module # TODO: migrate to InferenceInvocation +) # OpenAI Responses internals are version-gated (added in openai>=1.66.0), so # pylint may not resolve them in all lint environments even though we guard diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index 6afca130b6e..bd566ddba53 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -38,7 +38,7 @@ from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.genai.types import ( InputMessage, - LLMInvocation, + LLMInvocation, # pylint: disable=no-name-in-module # TODO: migrate to InferenceInvocation OutputMessage, Text, ToolCallRequest, diff --git a/util/opentelemetry-util-genai/AGENTS.md b/util/opentelemetry-util-genai/AGENTS.md new file mode 100644 index 00000000000..355d8b7c082 --- /dev/null +++ b/util/opentelemetry-util-genai/AGENTS.md @@ -0,0 +1,80 @@ +# GenAI Utils — Agent and Contributor Guidelines + +This package provides shared telemetry utilities for OpenTelemetry GenAI instrumentation. + +## 1. Semantic Convention Compliance + +All attributes, operation names, and span names must match the +[OpenTelemetry GenAI semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/) +exactly. + +Use the appropriate semconv attribute modules — do not hardcode attribute name strings: + +- `gen_ai.*` attributes: `opentelemetry.semconv._incubating.attributes.gen_ai_attributes` +- `server.*` attributes: `opentelemetry.semconv.attributes.server_attributes` +- `error.*` attributes: `opentelemetry.semconv.attributes.error_attributes` +- Other namespaces: use the corresponding module from `opentelemetry.semconv` + +## 2. Invocation Lifecycle Pattern + +Every new operation type must follow this pattern: + +```python +invocation = handler.start_inference(provider, request_model, server_address=..., server_port=...) +invocation.temperature = ... +try: + response = client.call(...) + invocation.response_model_name = response.model + invocation.finish_reasons = response.finish_reasons + invocation.stop() +except Exception as exc: + invocation.fail(exc) + raise +``` + +Factory methods on `TelemetryHandler` (`handler.py`): + +- `start_inference(provider, request_model, *, server_address, server_port)` → `InferenceInvocation` +- `start_embedding(provider, request_model, *, server_address, server_port)` → `EmbeddingInvocation` +- `start_tool(name, *, arguments, tool_call_id, tool_type, tool_description)` → `ToolInvocation` +- `start_workflow(name)` → `WorkflowInvocation` + +Context manager equivalents (`handler.inference()`, `handler.embedding()`, `handler.tool()`, +`handler.workflow()`) are available when the span lifetime maps cleanly to a `with` block. + +### Anti-patterns + +**Never construct invocation types directly** (`InferenceInvocation(...)`, `ToolInvocation(...)`, +etc.) in instrumentation or production code — direct construction skips span creation and context +propagation, so all telemetry calls become no-ops. Always use `handler.start_*()`. + +## 3. Exception Handling + +- Do not add `raise {Error}` statements to `handler.py` or `types.py` — validation belongs in + tests and callers, not telemetry internals. +- When catching exceptions from the underlying library to record telemetry, always re-raise + the original exception unmodified. + +## 4. Documentation + +- Docstrings for invocation types and span/event helpers must include a link to the + corresponding operation in the semconv spec. +- When adding or changing attributes, update the docstring to describe what is set and under + what conditions (e.g., "set only when `server_address` is provided"). + +## 5. Tests + +- Every new operation type or attribute change must have tests verifying the exact attribute + names and values produced, checked against the semconv spec. +- Cover all paths: success (`invocation.stop()`), failure (`invocation.fail(exc)`), and any + conditional attribute logic (e.g., attributes set only when optional fields are populated). +- Tests live in `tests/` — follow existing patterns there. +- Don't call internal API in tests when the public API is available. + +## 6. Python API Conventions + +- Mark private modules with an underscore. +- Objects inside of a private module should be prefixed with underscopre if they + are not used outside the that module. +- Before removing or renaming an object exposed publicly, deprecate it first with + `@deprecated("... Use X instead.")` pointing to the replacement; diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index 40b05bb3594..15914b8d610 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -7,10 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - - Add support for workflow in genAI utils handler. ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4366](#4366)) -- Enrich ToolCall type, breaking change: usage of ToolCall class renamed to ToolCallRequest +- Enrich ToolCall type, breaking change: usage of ToolCall class renamed to ToolCallRequest ([#4218](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4218)) - Add EmbeddingInvocation span lifecycle support ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4219](#4219)) @@ -20,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4310](#4310)) - Check if upload works at startup in initializer of the `UploadCompletionHook`, instead of repeatedly failing on every upload ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4390](#4390)). +- Refactor public API: add factory methods (`start_inference`, `start_embedding`, `start_tool`, `start_workflow`) and invocation-owned lifecycle (`invocation.stop()` / `invocation.fail(exc)`); rename `LLMInvocation` → `InferenceInvocation` and `ToolCall` → `ToolInvocation`. Existing usages remain fully functional via deprecated aliases. + ([#4391](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4391)) + ## Version 0.3b0 (2026-02-20) diff --git a/util/opentelemetry-util-genai/CLAUDE.md b/util/opentelemetry-util-genai/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/util/opentelemetry-util-genai/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/util/opentelemetry-util-genai/pyproject.toml b/util/opentelemetry-util-genai/pyproject.toml index be3ba572385..3e95fb30391 100644 --- a/util/opentelemetry-util-genai/pyproject.toml +++ b/util/opentelemetry-util-genai/pyproject.toml @@ -49,3 +49,4 @@ include = ["/src", "/tests"] [tool.hatch.build.targets.wheel] packages = ["src/opentelemetry"] + diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py new file mode 100644 index 00000000000..e7fa59b6000 --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py @@ -0,0 +1,124 @@ +# 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 __future__ import annotations + +from typing import Any + +from opentelemetry._logs import Logger +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.semconv.attributes import server_attributes +from opentelemetry.trace import SpanKind, Tracer +from opentelemetry.util.genai._invocation import Error, GenAIInvocation +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder +from opentelemetry.util.types import AttributeValue + + +class EmbeddingInvocation(GenAIInvocation): + """Represents a single embedding model invocation. + + Use handler.start_embedding(provider) or the handler.embedding(provider) + context manager rather than constructing this directly. + """ + + def __init__( + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + provider: str, + *, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + encoding_formats: list[str] | None = None, + input_tokens: int | None = None, + dimension_count: int | None = None, + response_model_name: str | None = None, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + """Use handler.start_embedding(provider) or handler.embedding(provider) instead of calling this directly.""" + _operation_name = GenAI.GenAiOperationNameValues.EMBEDDINGS.value + super().__init__( + tracer, + metrics_recorder, + logger, + operation_name=_operation_name, + span_name=f"{_operation_name} {request_model}" + if request_model + else _operation_name, + span_kind=SpanKind.CLIENT, + attributes=attributes, + metric_attributes=metric_attributes, + ) + self.provider = provider # e.g., azure.ai.openai, openai, aws.bedrock + self.request_model = request_model + self.server_address = server_address + self.server_port = server_port + # encoding_formats can be multi-value -> combinational cardinality risk. + # Keep on spans/events only. + self.encoding_formats = encoding_formats + self.input_tokens = input_tokens + self.dimension_count = dimension_count + self.response_model_name = response_model_name + self._start() + + def _get_metric_attributes(self) -> dict[str, Any]: + optional_attrs = ( + (GenAI.GEN_AI_PROVIDER_NAME, self.provider), + (GenAI.GEN_AI_REQUEST_MODEL, self.request_model), + (GenAI.GEN_AI_RESPONSE_MODEL, self.response_model_name), + (server_attributes.SERVER_ADDRESS, self.server_address), + (server_attributes.SERVER_PORT, self.server_port), + ) + attrs: dict[str, AttributeValue] = { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name, + **{k: v for k, v in optional_attrs if v is not None}, + } + attrs.update(self.metric_attributes) + return attrs + + def _get_metric_token_counts(self) -> dict[str, int]: + if self.input_tokens is not None: + return {GenAI.GenAiTokenTypeValues.INPUT.value: self.input_tokens} + return {} + + def _apply_finish(self, error: Error | None = None) -> None: + optional_attrs = ( + (GenAI.GEN_AI_PROVIDER_NAME, self.provider), + (server_attributes.SERVER_ADDRESS, self.server_address), + (server_attributes.SERVER_PORT, self.server_port), + (GenAI.GEN_AI_REQUEST_MODEL, self.request_model), + (GenAI.GEN_AI_EMBEDDINGS_DIMENSION_COUNT, self.dimension_count), + (GenAI.GEN_AI_REQUEST_ENCODING_FORMATS, self.encoding_formats), + (GenAI.GEN_AI_RESPONSE_MODEL, self.response_model_name), + (GenAI.GEN_AI_USAGE_INPUT_TOKENS, self.input_tokens), + ) + attributes: dict[str, Any] = { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name, + **{ + key: value + for key, value in optional_attrs + if value is not None + }, + } + if error is not None: + self._apply_error_attributes(error) + attributes.update(self.attributes) + self.span.set_attributes(attributes) + # Metrics recorder currently supports InferenceInvocation fields only. + # No-op until dedicated embedding metric support is added. diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py new file mode 100644 index 00000000000..a1bd55811c9 --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py @@ -0,0 +1,358 @@ +# 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 __future__ import annotations + +from dataclasses import asdict, dataclass, field +from typing import Any + +from opentelemetry._logs import Logger, LogRecord +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.semconv.attributes import server_attributes +from opentelemetry.trace import INVALID_SPAN, Span, SpanKind, Tracer +from opentelemetry.util.genai._invocation import Error, GenAIInvocation +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder +from opentelemetry.util.genai.types import ( + InputMessage, + MessagePart, + OutputMessage, +) +from opentelemetry.util.genai.utils import ( + ContentCapturingMode, + gen_ai_json_dumps, + get_content_capturing_mode, + is_experimental_mode, + should_emit_event, +) + + +class InferenceInvocation(GenAIInvocation): + """Represents a single LLM chat/completion call. + + Use handler.start_inference(provider) or the handler.inference(provider) + context manager rather than constructing this directly. + """ + + def __init__( # pylint: disable=too-many-locals + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + provider: str, + *, + request_model: str | None = None, + input_messages: list[InputMessage] | None = None, + output_messages: list[OutputMessage] | None = None, + system_instruction: list[MessagePart] | None = None, + response_model_name: str | None = None, + response_id: str | None = None, + finish_reasons: list[str] | None = None, + input_tokens: int | None = None, + output_tokens: int | None = None, + temperature: float | None = None, + top_p: float | None = None, + frequency_penalty: float | None = None, + presence_penalty: float | None = None, + max_tokens: int | None = None, + stop_sequences: list[str] | None = None, + seed: int | None = None, + server_address: str | None = None, + server_port: int | None = None, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + """Use handler.start_inference(provider) or handler.inference(provider) instead of calling this directly.""" + _operation_name = GenAI.GenAiOperationNameValues.CHAT.value + super().__init__( + tracer, + metrics_recorder, + logger, + operation_name=_operation_name, + span_name=f"{_operation_name} {request_model}" + if request_model + else _operation_name, + span_kind=SpanKind.CLIENT, + attributes=attributes, + metric_attributes=metric_attributes, + ) + self.provider = provider + self.request_model = request_model + self.input_messages: list[InputMessage] = ( + [] if input_messages is None else input_messages + ) + self.output_messages: list[OutputMessage] = ( + [] if output_messages is None else output_messages + ) + self.system_instruction: list[MessagePart] = ( + [] if system_instruction is None else system_instruction + ) + self.response_model_name = response_model_name + self.response_id = response_id + self.finish_reasons = finish_reasons + self.input_tokens = input_tokens + self.output_tokens = output_tokens + self.temperature = temperature + self.top_p = top_p + self.frequency_penalty = frequency_penalty + self.presence_penalty = presence_penalty + self.max_tokens = max_tokens + self.stop_sequences = stop_sequences + self.seed = seed + self.server_address = server_address + self.server_port = server_port + self._start() + + def _get_message_attributes(self, *, for_span: bool) -> dict[str, Any]: + if not is_experimental_mode(): + return {} + mode = get_content_capturing_mode() + allowed_modes = ( + ( + ContentCapturingMode.SPAN_ONLY, + ContentCapturingMode.SPAN_AND_EVENT, + ) + if for_span + else ( + ContentCapturingMode.EVENT_ONLY, + ContentCapturingMode.SPAN_AND_EVENT, + ) + ) + if mode not in allowed_modes: + return {} + + def serialize(items: list[Any]) -> Any: + dicts = [asdict(item) for item in items] + return gen_ai_json_dumps(dicts) if for_span else dicts + + optional_attrs = ( + ( + GenAI.GEN_AI_INPUT_MESSAGES, + serialize(self.input_messages) + if self.input_messages + else None, + ), + ( + GenAI.GEN_AI_OUTPUT_MESSAGES, + serialize(self.output_messages) + if self.output_messages + else None, + ), + ( + GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, + serialize(self.system_instruction) + if self.system_instruction + else None, + ), + ) + return { + key: value for key, value in optional_attrs if value is not None + } + + def _get_finish_reasons(self) -> list[str] | None: + if self.finish_reasons is not None: + return self.finish_reasons or None + if self.output_messages: + reasons = [ + msg.finish_reason + for msg in self.output_messages + if msg.finish_reason + ] + return reasons or None + return None + + def _get_base_attributes(self) -> dict[str, Any]: + optional_attrs = ( + (GenAI.GEN_AI_REQUEST_MODEL, self.request_model), + (GenAI.GEN_AI_PROVIDER_NAME, self.provider), + (server_attributes.SERVER_ADDRESS, self.server_address), + (server_attributes.SERVER_PORT, self.server_port), + ) + return { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name, + **{k: v for k, v in optional_attrs if v is not None}, + } + + def _get_attributes(self) -> dict[str, Any]: + attrs = self._get_base_attributes() + optional_attrs = ( + (GenAI.GEN_AI_REQUEST_TEMPERATURE, self.temperature), + (GenAI.GEN_AI_REQUEST_TOP_P, self.top_p), + (GenAI.GEN_AI_REQUEST_FREQUENCY_PENALTY, self.frequency_penalty), + (GenAI.GEN_AI_REQUEST_PRESENCE_PENALTY, self.presence_penalty), + (GenAI.GEN_AI_REQUEST_MAX_TOKENS, self.max_tokens), + (GenAI.GEN_AI_REQUEST_STOP_SEQUENCES, self.stop_sequences), + (GenAI.GEN_AI_REQUEST_SEED, self.seed), + (GenAI.GEN_AI_RESPONSE_FINISH_REASONS, self._get_finish_reasons()), + (GenAI.GEN_AI_RESPONSE_MODEL, self.response_model_name), + (GenAI.GEN_AI_RESPONSE_ID, self.response_id), + (GenAI.GEN_AI_USAGE_INPUT_TOKENS, self.input_tokens), + (GenAI.GEN_AI_USAGE_OUTPUT_TOKENS, self.output_tokens), + ) + attrs.update({k: v for k, v in optional_attrs if v is not None}) + return attrs + + def _get_metric_attributes(self) -> dict[str, Any]: + attrs = self._get_base_attributes() + if self.response_model_name is not None: + attrs[GenAI.GEN_AI_RESPONSE_MODEL] = self.response_model_name + attrs.update(self.metric_attributes) + return attrs + + def _get_metric_token_counts(self) -> dict[str, int]: + counts: dict[str, int] = {} + if self.input_tokens is not None: + counts[GenAI.GenAiTokenTypeValues.INPUT.value] = self.input_tokens + if self.output_tokens is not None: + counts[GenAI.GenAiTokenTypeValues.OUTPUT.value] = ( + self.output_tokens + ) + return counts + + def _apply_finish(self, error: Error | None = None) -> None: + if error is not None: + self._apply_error_attributes(error) + attributes = self._get_attributes() + attributes.update(self._get_message_attributes(for_span=True)) + attributes.update(self.attributes) + self.span.set_attributes(attributes) + self._metrics_recorder.record(self) + self._emit_event() + + def _emit_event(self) -> None: + """Emit a gen_ai.client.inference.operation.details event. + + For more details, see the semantic convention documentation: + https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md#event-eventgen_aiclientinferenceoperationdetails + """ + if not is_experimental_mode() or not should_emit_event(): + return + + attributes = self._get_attributes() + attributes.update(self._get_message_attributes(for_span=False)) + attributes.update(self.attributes) + self._logger.emit( + LogRecord( + event_name="gen_ai.client.inference.operation.details", + attributes=attributes, + context=self._span_context, + ) + ) + + +@dataclass +class LLMInvocation: + """Deprecated. Use InferenceInvocation instead. + + Data container for an LLM invocation. Pass to handler.start_llm() to start + the span, then update fields and call handler.stop_llm() or handler.fail_llm(). + """ + + request_model: str | None = None + input_messages: list[InputMessage] = field(default_factory=list) # pyright: ignore[reportUnknownVariableType] + output_messages: list[OutputMessage] = field(default_factory=list) # pyright: ignore[reportUnknownVariableType] + system_instruction: list[MessagePart] = field(default_factory=list) # pyright: ignore[reportUnknownVariableType] + provider: str | None = None + response_model_name: str | None = None + response_id: str | None = None + finish_reasons: list[str] | None = None + input_tokens: int | None = None + output_tokens: int | None = None + attributes: dict[str, Any] = field(default_factory=dict) # pyright: ignore[reportUnknownVariableType] + """Additional attributes to set on spans and/or events. Not set on metrics.""" + metric_attributes: dict[str, Any] = field(default_factory=dict) # pyright: ignore[reportUnknownVariableType] + """Additional attributes to set on metrics. Must be low cardinality. Not set on spans or events.""" + temperature: float | None = None + top_p: float | None = None + frequency_penalty: float | None = None + presence_penalty: float | None = None + max_tokens: int | None = None + stop_sequences: list[str] | None = None + seed: int | None = None + server_address: str | None = None + server_port: int | None = None + + _inference_invocation: InferenceInvocation | None = field( + default=None, init=False, repr=False + ) + + def _start_with_handler( + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + ) -> None: + """Create and start an InferenceInvocation from this data container. Called by handler.start_llm().""" + self._inference_invocation = InferenceInvocation( + tracer, + metrics_recorder, + logger, + self.provider or "", + request_model=self.request_model, + input_messages=self.input_messages, + output_messages=self.output_messages, + system_instruction=self.system_instruction, + response_model_name=self.response_model_name, + response_id=self.response_id, + finish_reasons=self.finish_reasons, + input_tokens=self.input_tokens, + output_tokens=self.output_tokens, + temperature=self.temperature, + top_p=self.top_p, + frequency_penalty=self.frequency_penalty, + presence_penalty=self.presence_penalty, + max_tokens=self.max_tokens, + stop_sequences=self.stop_sequences, + seed=self.seed, + server_address=self.server_address, + server_port=self.server_port, + attributes=self.attributes, + metric_attributes=self.metric_attributes, + ) + + def _sync_to_invocation(self) -> None: + inv = self._inference_invocation + if inv is None: + return + inv.provider = self.provider or "" + inv.request_model = self.request_model + inv.input_messages = self.input_messages + inv.output_messages = self.output_messages + inv.system_instruction = self.system_instruction + inv.response_model_name = self.response_model_name + inv.response_id = self.response_id + inv.finish_reasons = self.finish_reasons + inv.input_tokens = self.input_tokens + inv.output_tokens = self.output_tokens + inv.temperature = self.temperature + inv.top_p = self.top_p + inv.frequency_penalty = self.frequency_penalty + inv.presence_penalty = self.presence_penalty + inv.max_tokens = self.max_tokens + inv.stop_sequences = self.stop_sequences + inv.seed = self.seed + inv.server_address = self.server_address + inv.server_port = self.server_port + inv.attributes = self.attributes + inv.metric_attributes = self.metric_attributes + + @property + def span(self) -> Span: + """The underlying span, for back-compat with code that checks span.is_recording().""" + return ( + self._inference_invocation.span + if self._inference_invocation is not None + else INVALID_SPAN + ) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_invocation.py new file mode 100644 index 00000000000..b63d9a32b4f --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_invocation.py @@ -0,0 +1,140 @@ +# 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 __future__ import annotations + +import timeit +from abc import ABC, abstractmethod +from contextlib import contextmanager +from contextvars import Token +from typing import TYPE_CHECKING, Any, Iterator + +from typing_extensions import Self, TypeAlias + +from opentelemetry._logs import Logger +from opentelemetry.context import Context, attach, detach +from opentelemetry.semconv.attributes import error_attributes +from opentelemetry.trace import INVALID_SPAN as _INVALID_SPAN +from opentelemetry.trace import Span, SpanKind, Tracer, set_span_in_context +from opentelemetry.trace.status import Status, StatusCode +from opentelemetry.util.genai.types import Error + +if TYPE_CHECKING: + from opentelemetry.util.genai.metrics import InvocationMetricsRecorder + +ContextToken: TypeAlias = Token[Context] + + +class GenAIInvocation(ABC): + """ + Base class for all GenAI invocation types. Manages the lifecycle of a single + GenAI operation (LLM call, embedding, tool execution, workflow, etc.). + + Use the factory methods on TelemetryHandler (start_inference, start_embedding, + start_workflow, start_tool) rather than constructing invocations directly. + """ + + def __init__( + self, + # Individual components instead of TelemetryHandler to avoid a circular + # import between handler.py and the invocation modules. + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + operation_name: str, + span_name: str, + span_kind: SpanKind = SpanKind.CLIENT, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + self._tracer = tracer + self._metrics_recorder = metrics_recorder + self._logger = logger + self._operation_name: str = operation_name + self.attributes: dict[str, Any] = ( + {} if attributes is None else attributes + ) + """Additional attributes to set on spans and/or events. Not set on metrics.""" + self.metric_attributes: dict[str, Any] = ( + {} if metric_attributes is None else metric_attributes + ) + """Additional attributes to set on metrics. Must be low cardinality. Not set on spans or events.""" + self.span: Span = _INVALID_SPAN + self._span_context: Context + self._span_name: str = span_name + self._span_kind: SpanKind = span_kind + self._context_token: ContextToken | None = None + self._monotonic_start_s: float | None = None + + def _start(self) -> None: + """Start the invocation span and attach it to the current context.""" + self.span = self._tracer.start_span( + name=self._span_name, + kind=self._span_kind, + ) + self._span_context = set_span_in_context(self.span) + self._monotonic_start_s = timeit.default_timer() + self._context_token = attach(self._span_context) + + def _get_metric_attributes(self) -> dict[str, Any]: + """Return low-cardinality attributes for metric recording.""" + return self.metric_attributes + + def _get_metric_token_counts(self) -> dict[str, int]: # pylint: disable=no-self-use + """Return {token_type: count} for token histogram recording.""" + return {} + + def _apply_error_attributes(self, error: Error) -> None: + """Apply error status and error.type attribute to the span, events, and metrics.""" + error_type = error.type.__qualname__ + self.span.set_status(Status(StatusCode.ERROR, error.message)) + self.attributes[error_attributes.ERROR_TYPE] = error_type + self.metric_attributes[error_attributes.ERROR_TYPE] = error_type + + @abstractmethod + def _apply_finish(self, error: Error | None = None) -> None: + """Apply finish telemetry (attributes, metrics, events).""" + + def _finish(self, error: Error | None = None) -> None: + """Apply finish telemetry and end the span.""" + if self._context_token is None: + return + try: + self._apply_finish(error) + finally: + try: + detach(self._context_token) + except Exception: # pylint: disable=broad-except + pass + self.span.end() + + def stop(self) -> None: + """Finalize the invocation successfully and end its span.""" + self._finish() + + def fail(self, error: Error | BaseException) -> None: + """Fail the invocation and end its span with error status.""" + if isinstance(error, BaseException): + error = Error(type=type(error), message=str(error)) + self._finish(error) + + @contextmanager + def _managed(self) -> Iterator[Self]: + """Context manager that calls stop() on success or fail() on exception.""" + try: + yield self + except Exception as exc: + self.fail(exc) + raise + self.stop() diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py new file mode 100644 index 00000000000..1ebbd85bc69 --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py @@ -0,0 +1,96 @@ +# 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 __future__ import annotations + +from typing import Any + +from opentelemetry._logs import Logger +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.trace import Tracer +from opentelemetry.util.genai._invocation import Error, GenAIInvocation +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder + + +class ToolInvocation(GenAIInvocation): + """Represents a tool call invocation for execute_tool span tracking. + + Not used as a message part — use ToolCallRequest for that purpose. + + Use handler.start_tool(name) rather than constructing this directly. + + Reference: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md#execute-tool-span + + Semantic convention attributes for execute_tool spans: + - gen_ai.operation.name: "execute_tool" (Required) + - gen_ai.tool.name: Name of the tool (Recommended) + - gen_ai.tool.call.id: Tool call identifier (Recommended if available) + - gen_ai.tool.type: Type classification - "function", "extension", or "datastore" (Recommended if available) + - gen_ai.tool.description: Tool description (Recommended if available) + - gen_ai.tool.call.arguments: Parameters passed to tool (Opt-In, may contain sensitive data) + - gen_ai.tool.call.result: Result returned by tool (Opt-In, may contain sensitive data) + - error.type: Error type if operation failed (Conditionally Required) + """ + + def __init__( + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + name: str, + *, + arguments: Any = None, + tool_call_id: str | None = None, + tool_type: str | None = None, + tool_description: str | None = None, + tool_result: Any = None, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + """Use handler.start_tool(name) or handler.tool(name) instead of calling this directly.""" + _operation_name = GenAI.GenAiOperationNameValues.EXECUTE_TOOL.value + super().__init__( + tracer, + metrics_recorder, + logger, + operation_name=_operation_name, + span_name=f"{_operation_name} {name}" if name else _operation_name, + attributes=attributes, + metric_attributes=metric_attributes, + ) + self.name = name + self.arguments = arguments + self.tool_call_id = tool_call_id + self.tool_type = tool_type + self.tool_description = tool_description + self.tool_result = tool_result + self._start() + + def _apply_finish(self, error: Error | None = None) -> None: + if error is not None: + self._apply_error_attributes(error) + optional_attrs = ( + (GenAI.GEN_AI_TOOL_NAME, self.name), + (GenAI.GEN_AI_TOOL_CALL_ID, self.tool_call_id), + (GenAI.GEN_AI_TOOL_TYPE, self.tool_type), + (GenAI.GEN_AI_TOOL_DESCRIPTION, self.tool_description), + ) + attributes: dict[str, Any] = { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name, + **{k: v for k, v in optional_attrs if v is not None}, + } + attributes.update(self.attributes) + self.span.set_attributes(attributes) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_workflow_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_workflow_invocation.py new file mode 100644 index 00000000000..e3b45535d29 --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_workflow_invocation.py @@ -0,0 +1,115 @@ +# 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 __future__ import annotations + +from dataclasses import asdict +from typing import Any + +from opentelemetry._logs import Logger +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.trace import SpanKind, Tracer +from opentelemetry.util.genai._invocation import Error, GenAIInvocation +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder +from opentelemetry.util.genai.types import ( + InputMessage, + OutputMessage, +) +from opentelemetry.util.genai.utils import ( + ContentCapturingMode, + gen_ai_json_dumps, + get_content_capturing_mode, + is_experimental_mode, +) + + +class WorkflowInvocation(GenAIInvocation): + """ + Represents a predetermined sequence of operations (e.g. agent, LLM, tool, + and retrieval invocations). A workflow groups multiple operations together, + accepting input(s) and producing final output(s). + + Use handler.start_workflow(name) or the handler.workflow(name) context + manager rather than constructing this directly. + """ + + def __init__( + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + name: str | None, + *, + input_messages: list[InputMessage] | None = None, + output_messages: list[OutputMessage] | None = None, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + """Use handler.start_workflow(name) or handler.workflow(name) instead of calling this directly.""" + _operation_name = "invoke_workflow" + super().__init__( + tracer, + metrics_recorder, + logger, + operation_name=_operation_name, + span_name=f"{_operation_name} {name}" if name else _operation_name, + span_kind=SpanKind.INTERNAL, + attributes=attributes, + metric_attributes=metric_attributes, + ) + self.name = name + self.input_messages: list[InputMessage] = ( + [] if input_messages is None else input_messages + ) + self.output_messages: list[OutputMessage] = ( + [] if output_messages is None else output_messages + ) + self._start() + + def _get_messages_for_span(self) -> dict[str, Any]: + if not is_experimental_mode() or get_content_capturing_mode() not in ( + ContentCapturingMode.SPAN_ONLY, + ContentCapturingMode.SPAN_AND_EVENT, + ): + return {} + optional_attrs = ( + ( + GenAI.GEN_AI_INPUT_MESSAGES, + gen_ai_json_dumps([asdict(m) for m in self.input_messages]) + if self.input_messages + else None, + ), + ( + GenAI.GEN_AI_OUTPUT_MESSAGES, + gen_ai_json_dumps([asdict(m) for m in self.output_messages]) + if self.output_messages + else None, + ), + ) + return { + key: value for key, value in optional_attrs if value is not None + } + + def _apply_finish(self, error: Error | None = None) -> None: + attributes: dict[str, Any] = { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name + } + attributes.update(self._get_messages_for_span()) + if error is not None: + self._apply_error_attributes(error) + attributes.update(self.attributes) + self.span.set_attributes(attributes) + # TODO: Add workflow metrics when supported diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py index 858e8a8237c..9ef4a5592d6 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py @@ -17,7 +17,6 @@ This module exposes the `TelemetryHandler` class, which manages the lifecycle of GenAI (Generative AI) invocations and emits telemetry data (spans and related attributes). -It supports starting, stopping, and failing LLM invocations. Classes: - TelemetryHandler: Manages GenAI invocation lifecycles and emits telemetry. @@ -28,44 +27,29 @@ Usage: handler = get_telemetry_handler() - # Create an invocation object with your request data - # The span and context_token attributes are set by the TelemetryHandler, and - # managed by the TelemetryHandler during the lifecycle of the span. - - # Use the context manager to manage the lifecycle of an LLM invocation. - with handler.llm(invocation) as invocation: - # Populate outputs and any additional attributes + # Factory method: construct and start in one call, then stop or fail. + invocation = handler.start_inference("my-provider", request_model="my-model") + invocation.input_messages = [...] + invocation.temperature = 0.7 + try: + # ... call the underlying library ... + invocation.output_messages = [...] + invocation.stop() + except Exception as exc: + invocation.fail(exc) + raise + + # Or use the context manager form — exception handling is automatic. + with handler.inference("my-provider", request_model="my-model") as invocation: + invocation.input_messages = [...] + # ... call the underlying library ... invocation.output_messages = [...] - invocation.attributes.update({"more": "attrs"}) - - # Or, if you prefer to manage the lifecycle manually - invocation = LLMInvocation( - request_model="my-model", - input_messages=[...], - provider="my-provider", - attributes={"custom": "attr"}, - ) - - # Start the invocation (opens a span) - handler.start_llm(invocation) - - # Populate outputs and any additional attributes, then stop (closes the span) - invocation.output_messages = [...] - invocation.attributes.update({"more": "attrs"}) - handler.stop_llm(invocation) - - # Or, in case of error - handler.fail_llm(invocation, Error(type="...", message="...")) """ from __future__ import annotations -import logging -import timeit -from contextlib import contextmanager -from typing import Iterator, TypeVar +from contextlib import AbstractContextManager -from opentelemetry import context as otel_context from opentelemetry._logs import ( LoggerProvider, get_logger, @@ -73,51 +57,22 @@ from opentelemetry.metrics import MeterProvider, get_meter from opentelemetry.semconv.schemas import Schemas from opentelemetry.trace import ( - Span, - SpanKind, TracerProvider, get_tracer, - set_span_in_context, ) -from opentelemetry.util.genai.metrics import InvocationMetricsRecorder -from opentelemetry.util.genai.span_utils import ( - _apply_embedding_finish_attributes, - _apply_error_attributes, - _apply_llm_finish_attributes, - _apply_workflow_finish_attributes, - _get_embedding_span_name, - _get_llm_span_name, - _get_workflow_span_name, - _maybe_emit_llm_event, +from opentelemetry.util.genai._inference_invocation import ( + LLMInvocation, ) -from opentelemetry.util.genai.types import ( +from opentelemetry.util.genai._invocation import Error +from opentelemetry.util.genai.invocation import ( EmbeddingInvocation, - Error, - GenAIInvocation, - LLMInvocation, + InferenceInvocation, + ToolInvocation, WorkflowInvocation, ) +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder from opentelemetry.util.genai.version import __version__ -_logger = logging.getLogger(__name__) - - -def _safe_detach(invocation: GenAIInvocation) -> None: - """Detach the context token if still present, as a safety net.""" - if invocation.context_token is not None: - try: - otel_context.detach(invocation.context_token) - except Exception: # pylint: disable=broad-except - pass - if invocation.span is not None: - try: - invocation.span.end() - except Exception: # pylint: disable=broad-except - pass - - -_T = TypeVar("_T", bound=GenAIInvocation) - class TelemetryHandler: """ @@ -138,7 +93,6 @@ def __init__( tracer_provider, schema_url=schema_url, ) - self._metrics_recorder: InvocationMetricsRecorder | None = None meter = get_meter( __name__, meter_provider=meter_provider, schema_url=schema_url ) @@ -150,153 +104,139 @@ def __init__( schema_url=schema_url, ) - def _record_llm_metrics( + # New-style factory methods: construct + start in one call, handler stored on invocation + + def start_inference( self, - invocation: LLMInvocation, - span: Span | None = None, + provider: str, *, - error_type: str | None = None, - ) -> None: - if self._metrics_recorder is None or span is None: - return - self._metrics_recorder.record( - span, - invocation, - error_type=error_type, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + ) -> InferenceInvocation: + """Create and start an LLM inference invocation. + + Set remaining attributes (input_messages, temperature, etc.) on the + returned invocation, then call invocation.stop() or invocation.fail(). + """ + return InferenceInvocation( + self._tracer, + self._metrics_recorder, + self._logger, + provider, + request_model=request_model, + server_address=server_address, + server_port=server_port, ) - @staticmethod - def _record_embedding_metrics( - invocation: EmbeddingInvocation, - span: Span | None = None, - *, - error_type: str | None = None, - ) -> None: - # Metrics recorder currently supports LLMInvocation fields only. - # Keep embedding metrics as a no-op until dedicated embedding - # metric support is added. - return - - def _start(self, invocation: _T) -> _T: - """Start a GenAI invocation and create a pending span entry.""" - if isinstance(invocation, LLMInvocation): - span_name = _get_llm_span_name(invocation) - kind = SpanKind.CLIENT - elif isinstance(invocation, EmbeddingInvocation): - span_name = _get_embedding_span_name(invocation) - kind = SpanKind.CLIENT - elif isinstance(invocation, WorkflowInvocation): - span_name = _get_workflow_span_name(invocation) - kind = SpanKind.INTERNAL - else: - span_name = "" - kind = SpanKind.CLIENT - span = self._tracer.start_span( - name=span_name, - kind=kind, - ) - # Record a monotonic start timestamp (seconds) for duration - # calculation using timeit.default_timer. - invocation.monotonic_start_s = timeit.default_timer() - invocation.span = span - invocation.context_token = otel_context.attach( - set_span_in_context(span) - ) - return invocation + def start_llm(self, invocation: LLMInvocation) -> LLMInvocation: + """Start an LLM invocation. - def _stop(self, invocation: _T) -> _T: - """Finalize a GenAI invocation successfully and end its span.""" - if invocation.context_token is None or invocation.span is None: - # TODO: Provide feedback that this invocation was not started - return invocation - - span = invocation.span - try: - if isinstance(invocation, LLMInvocation): - _apply_llm_finish_attributes(span, invocation) - self._record_llm_metrics(invocation, span) - _maybe_emit_llm_event(self._logger, span, invocation) - elif isinstance(invocation, EmbeddingInvocation): - _apply_embedding_finish_attributes(span, invocation) - self._record_embedding_metrics(invocation, span) - elif isinstance(invocation, WorkflowInvocation): - _apply_workflow_finish_attributes(span, invocation) - # TODO: Add workflow metrics when supported - finally: - # Detach context and end span even if finishing fails - otel_context.detach(invocation.context_token) - span.end() + .. deprecated:: + Use ``handler.start_inference()`` instead. + """ + invocation._start_with_handler( + self._tracer, self._metrics_recorder, self._logger + ) return invocation - def _fail(self, invocation: _T, error: Error) -> _T: - """Fail a GenAI invocation and end its span with error status.""" - if invocation.context_token is None or invocation.span is None: - # TODO: Provide feedback that this invocation was not started - return invocation - - span = invocation.span - error_type = error.type.__qualname__ - try: - if isinstance(invocation, LLMInvocation): - _apply_llm_finish_attributes(span, invocation) - _apply_error_attributes(span, error, error_type) - self._record_llm_metrics( - invocation, span, error_type=error_type - ) - _maybe_emit_llm_event( - self._logger, span, invocation, error_type - ) - elif isinstance(invocation, EmbeddingInvocation): - _apply_embedding_finish_attributes(span, invocation) - _apply_error_attributes(span, error, error_type) - self._record_embedding_metrics( - invocation, span, error_type=error_type - ) - elif isinstance(invocation, WorkflowInvocation): - _apply_workflow_finish_attributes(span, invocation) - _apply_error_attributes(span, error, error_type) - # TODO: Add workflow metrics when supported - finally: - # Detach context and end span even if finishing fails - otel_context.detach(invocation.context_token) - span.end() - return invocation + def start_embedding( + self, + provider: str, + *, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + ) -> EmbeddingInvocation: + """Create and start an Embedding invocation. + + Set remaining attributes (encoding_formats, etc.) on the returned + invocation, then call invocation.stop() or invocation.fail(). + """ + return EmbeddingInvocation( + self._tracer, + self._metrics_recorder, + self._logger, + provider, + request_model=request_model, + server_address=server_address, + server_port=server_port, + ) - def start( + def start_tool( self, - invocation: _T, - ) -> _T: - """Start a GenAI invocation and create a pending span entry.""" - return self._start(invocation) + name: str, + *, + arguments: object = None, + tool_call_id: str | None = None, + tool_type: str | None = None, + tool_description: str | None = None, + ) -> ToolInvocation: + """Create and start a tool invocation. + + Set tool_result on the returned invocation when done, then call + invocation.stop() or invocation.fail(). + """ + return ToolInvocation( + self._tracer, + self._metrics_recorder, + self._logger, + name, + arguments=arguments, + tool_call_id=tool_call_id, + tool_type=tool_type, + tool_description=tool_description, + ) - def stop(self, invocation: _T) -> _T: - """Finalize a GenAI invocation successfully and end its span.""" - return self._stop(invocation) + def start_workflow( + self, + *, + name: str | None = None, + ) -> WorkflowInvocation: + """Create and start a workflow invocation. - def fail(self, invocation: _T, error: Error) -> _T: - """Fail a GenAI invocation and end its span with error status.""" - return self._fail(invocation, error) + Set remaining attributes on the returned invocation, then call + invocation.stop() or invocation.fail(). + """ + return WorkflowInvocation( + self._tracer, self._metrics_recorder, self._logger, name + ) - # LLM-specific convenience methods - def start_llm(self, invocation: LLMInvocation) -> LLMInvocation: - """Start an LLM invocation and create a pending span entry.""" - return self._start(invocation) + def stop_llm(self, invocation: LLMInvocation) -> LLMInvocation: # pylint: disable=no-self-use + """Finalize an LLM invocation successfully and end its span. - def stop_llm(self, invocation: LLMInvocation) -> LLMInvocation: - """Finalize an LLM invocation successfully and end its span.""" - return self._stop(invocation) + .. deprecated:: + Use ``handler.start_inference()`` and then ``inference.stop()`` instead. + """ + invocation._sync_to_invocation() + if invocation._inference_invocation is not None: + invocation._inference_invocation.stop() + return invocation - def fail_llm( - self, invocation: LLMInvocation, error: Error + def fail_llm( # pylint: disable=no-self-use + self, + invocation: LLMInvocation, + error: Error, ) -> LLMInvocation: - """Fail an LLM invocation and end its span with error status.""" - return self._fail(invocation, error) + """Fail an LLM invocation and end its span with error status. - @contextmanager - def llm( - self, invocation: LLMInvocation | None = None - ) -> Iterator[LLMInvocation]: - """Context manager for LLM invocations. + .. deprecated:: + Use ``handler.start_inference()`` and then ``inference.fail()`` instead. + """ + invocation._sync_to_invocation() + if invocation._inference_invocation is not None: + invocation._inference_invocation.fail(error) + return invocation + + def inference( + self, + provider: str, + *, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + ) -> AbstractContextManager[InferenceInvocation]: + """Context manager for LLM inference invocations. Only set data attributes on the invocation object, do not modify the span or context. @@ -304,22 +244,21 @@ def llm( If an exception occurs inside the context, marks the span as error, ends it, and re-raises the original exception. """ - if invocation is None: - invocation = LLMInvocation( - request_model="", - ) - self.start_llm(invocation) - try: - yield invocation - except Exception as exc: - self.fail_llm(invocation, Error(message=str(exc), type=type(exc))) - raise - self.stop_llm(invocation) - - @contextmanager + return self.start_inference( + provider=provider, + request_model=request_model, + server_address=server_address, + server_port=server_port, + )._managed() + def embedding( - self, invocation: EmbeddingInvocation | None = None - ) -> Iterator[EmbeddingInvocation]: + self, + provider: str, + *, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + ) -> AbstractContextManager[EmbeddingInvocation]: """Context manager for Embedding invocations. Only set data attributes on the invocation object, do not modify the span or context. @@ -328,20 +267,42 @@ def embedding( If an exception occurs inside the context, marks the span as error, ends it, and re-raises the original exception. """ - if invocation is None: - invocation = EmbeddingInvocation() - self.start(invocation) - try: - yield invocation - except Exception as exc: - self.fail(invocation, Error(message=str(exc), type=type(exc))) - raise - self.stop(invocation) - - @contextmanager + return self.start_embedding( + provider=provider, + request_model=request_model, + server_address=server_address, + server_port=server_port, + )._managed() + + def tool( + self, + name: str, + *, + arguments: object = None, + tool_call_id: str | None = None, + tool_type: str | None = None, + tool_description: str | None = None, + ) -> AbstractContextManager[ToolInvocation]: + """Context manager for Tool invocations. + + Only set data attributes on the invocation object, do not modify the span or context. + + Starts the span on entry. On normal exit, finalizes the invocation and ends the span. + If an exception occurs inside the context, marks the span as error, ends it, and + re-raises the original exception. + """ + return self.start_tool( + name, + arguments=arguments, + tool_call_id=tool_call_id, + tool_type=tool_type, + tool_description=tool_description, + )._managed() + def workflow( - self, invocation: WorkflowInvocation | None = None - ) -> Iterator[WorkflowInvocation]: + self, + name: str | None = None, + ) -> AbstractContextManager[WorkflowInvocation]: """Context manager for Workflow invocations. Only set data attributes on the invocation object, do not modify the span or context. @@ -350,33 +311,7 @@ def workflow( If an exception occurs inside the context, marks the span as error, ends it, and re-raises the original exception. """ - if invocation is None: - invocation = WorkflowInvocation() - - try: - self.start(invocation) - except Exception: # pylint: disable=broad-except - _logger.warning( - "Failed to start workflow telemetry", exc_info=True - ) - - try: - yield invocation - except Exception as exc: - try: - self.fail(invocation, Error(message=str(exc), type=type(exc))) - except Exception: # pylint: disable=broad-except - _logger.warning( - "Failed to record workflow failure", exc_info=True - ) - _safe_detach(invocation) - raise - - try: - self.stop(invocation) - except Exception: # pylint: disable=broad-except - _logger.warning("Failed to stop workflow telemetry", exc_info=True) - _safe_detach(invocation) + return self.start_workflow(name=name)._managed() def get_telemetry_handler( diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/invocation.py new file mode 100644 index 00000000000..4ac6426ce1d --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/invocation.py @@ -0,0 +1,47 @@ +# 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. + +"""Public re-export of all GenAI invocation types. + +Users can import everything from this single module: + + from opentelemetry.util.genai.invocation import ( + Error, + GenAIInvocation, + InferenceInvocation, + EmbeddingInvocation, + ToolInvocation, + WorkflowInvocation, + ) +""" + +from opentelemetry.util.genai._embedding_invocation import EmbeddingInvocation +from opentelemetry.util.genai._inference_invocation import InferenceInvocation +from opentelemetry.util.genai._invocation import ( + ContextToken, + Error, + GenAIInvocation, +) +from opentelemetry.util.genai._tool_invocation import ToolInvocation +from opentelemetry.util.genai._workflow_invocation import WorkflowInvocation + +__all__ = [ + "ContextToken", + "Error", + "GenAIInvocation", + "InferenceInvocation", + "EmbeddingInvocation", + "ToolInvocation", + "WorkflowInvocation", +] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py index 075cbe60a1f..144f4663b6e 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py @@ -3,23 +3,18 @@ from __future__ import annotations import timeit -from typing import Dict, Optional +from typing import Optional from opentelemetry.metrics import Histogram, Meter from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAI, ) -from opentelemetry.semconv.attributes import ( - error_attributes, - server_attributes, -) -from opentelemetry.trace import Span, set_span_in_context from opentelemetry.util.genai.instruments import ( create_duration_histogram, create_token_histogram, ) -from opentelemetry.util.genai.types import LLMInvocation -from opentelemetry.util.types import AttributeValue + +from ._invocation import GenAIInvocation class InvocationMetricsRecorder: @@ -29,80 +24,30 @@ def __init__(self, meter: Meter): self._duration_histogram: Histogram = create_duration_histogram(meter) self._token_histogram: Histogram = create_token_histogram(meter) - def record( - self, - span: Optional[Span], - invocation: LLMInvocation, - *, - error_type: Optional[str] = None, - ) -> None: + def record(self, invocation: GenAIInvocation) -> None: """Record duration and token metrics for an invocation if possible.""" + attributes = invocation._get_metric_attributes() + token_counts = invocation._get_metric_token_counts() - # pylint: disable=too-many-branches - - if span is None: - return - - token_counts: list[tuple[int, str]] = [] - if invocation.input_tokens is not None: - token_counts.append( - ( - invocation.input_tokens, - GenAI.GenAiTokenTypeValues.INPUT.value, - ) - ) - if invocation.output_tokens is not None: - token_counts.append( - ( - invocation.output_tokens, - GenAI.GenAiTokenTypeValues.OUTPUT.value, - ) - ) - - attributes: Dict[str, AttributeValue] = { - GenAI.GEN_AI_OPERATION_NAME: GenAI.GenAiOperationNameValues.CHAT.value - } - if invocation.request_model: - attributes[GenAI.GEN_AI_REQUEST_MODEL] = invocation.request_model - if invocation.provider: - attributes[GenAI.GEN_AI_PROVIDER_NAME] = invocation.provider - if invocation.response_model_name: - attributes[GenAI.GEN_AI_RESPONSE_MODEL] = ( - invocation.response_model_name - ) - if invocation.server_address: - attributes[server_attributes.SERVER_ADDRESS] = ( - invocation.server_address - ) - if invocation.server_port is not None: - attributes[server_attributes.SERVER_PORT] = invocation.server_port - if invocation.metric_attributes: - attributes.update(invocation.metric_attributes) - - # Calculate duration from span timing or invocation monotonic start duration_seconds: Optional[float] = None - if invocation.monotonic_start_s is not None: + if invocation._monotonic_start_s is not None: duration_seconds = max( - timeit.default_timer() - invocation.monotonic_start_s, + timeit.default_timer() - invocation._monotonic_start_s, 0.0, ) - span_context = set_span_in_context(span) - if error_type: - attributes[error_attributes.ERROR_TYPE] = error_type - if duration_seconds is not None: self._duration_histogram.record( duration_seconds, attributes=attributes, - context=span_context, + context=invocation._span_context, ) - for token_count, token_type in token_counts: + for token_type, token_count in token_counts.items(): self._token_histogram.record( token_count, attributes=attributes | {GenAI.GEN_AI_TOKEN_TYPE: token_type}, - context=span_context, + context=invocation._span_context, ) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py deleted file mode 100644 index 0a82462c1bb..00000000000 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py +++ /dev/null @@ -1,417 +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 __future__ import annotations - -from dataclasses import asdict -from typing import Any - -from opentelemetry._logs import Logger, LogRecord -from opentelemetry.context import get_current -from opentelemetry.semconv._incubating.attributes import ( - gen_ai_attributes as GenAI, -) -from opentelemetry.semconv.attributes import ( - error_attributes, - server_attributes, -) -from opentelemetry.trace import ( - Span, -) -from opentelemetry.trace.propagation import set_span_in_context -from opentelemetry.trace.status import Status, StatusCode -from opentelemetry.util.genai.types import ( - EmbeddingInvocation, - Error, - GenAIInvocation, - InputMessage, - LLMInvocation, - MessagePart, - OutputMessage, - WorkflowInvocation, -) -from opentelemetry.util.genai.utils import ( - ContentCapturingMode, - gen_ai_json_dumps, - get_content_capturing_mode, - is_experimental_mode, - should_emit_event, -) - - -def _get_llm_common_attributes( - invocation: LLMInvocation, -) -> dict[str, Any]: - """Get common LLM attributes shared by finish() and error() paths. - - Returns a dictionary of attributes. - """ - # TODO: clean provider name to match GenAiProviderNameValues? - optional_attrs = ( - (GenAI.GEN_AI_REQUEST_MODEL, invocation.request_model), - (GenAI.GEN_AI_PROVIDER_NAME, invocation.provider), - (server_attributes.SERVER_ADDRESS, invocation.server_address), - (server_attributes.SERVER_PORT, invocation.server_port), - ) - - return { - GenAI.GEN_AI_OPERATION_NAME: invocation.operation_name, - **{key: value for key, value in optional_attrs if value is not None}, - } - - -def _get_embedding_common_attributes( - invocation: EmbeddingInvocation, -) -> dict[str, Any]: - """Get common Embedding attributes shared by finish() and error() paths. - - Returns a dictionary of attributes. - """ - optional_attrs = ( - (server_attributes.SERVER_ADDRESS, invocation.server_address), - (server_attributes.SERVER_PORT, invocation.server_port), - ) - - return { - GenAI.GEN_AI_OPERATION_NAME: invocation.operation_name, - GenAI.GEN_AI_PROVIDER_NAME: invocation.provider, - **{key: value for key, value in optional_attrs if value is not None}, - } - - -def _get_span_name( - invocation: GenAIInvocation, -) -> str: - """Get the span name for a GenAI invocation.""" - operation_name = getattr(invocation, "operation_name", None) or "" - request_model = getattr(invocation, "request_model", None) or "" - return f"{operation_name} {request_model}".strip() - - -def _get_llm_span_name(invocation: LLMInvocation) -> str: - """Get the span name for an LLM invocation.""" - return _get_span_name(invocation) - - -def _get_embedding_span_name(invocation: EmbeddingInvocation) -> str: - """Get the span name for an Embedding invocation.""" - return _get_span_name(invocation) - - -def _get_workflow_span_name(invocation: WorkflowInvocation) -> str: - """Get the span name for an Workflow invocation.""" - operation_name = invocation.operation_name - name = invocation.name - return f"{operation_name} {name}" if name else operation_name - - -def _get_messages_attributes_for_span( - input_messages: list[InputMessage], - output_messages: list[OutputMessage], - system_instruction: list[MessagePart] | None = None, -) -> dict[str, Any]: - """Get message attributes formatted for span (JSON string format). - - Returns empty dict if not in experimental mode or content capturing is disabled. - """ - if not is_experimental_mode() or get_content_capturing_mode() not in ( - ContentCapturingMode.SPAN_ONLY, - ContentCapturingMode.SPAN_AND_EVENT, - ): - return {} - - optional_attrs = ( - ( - GenAI.GEN_AI_INPUT_MESSAGES, - gen_ai_json_dumps([asdict(m) for m in input_messages]) - if input_messages - else None, - ), - ( - GenAI.GEN_AI_OUTPUT_MESSAGES, - gen_ai_json_dumps([asdict(m) for m in output_messages]) - if output_messages - else None, - ), - ( - GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, - gen_ai_json_dumps([asdict(p) for p in system_instruction]) - if system_instruction - else None, - ), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _get_llm_messages_attributes_for_event( - input_messages: list[InputMessage], - output_messages: list[OutputMessage], - system_instruction: list[MessagePart] | None = None, -) -> dict[str, Any]: - """Get message attributes formatted for event (structured format). - - Returns empty dict if not in experimental mode or content capturing is disabled. - """ - if not is_experimental_mode() or get_content_capturing_mode() not in ( - ContentCapturingMode.EVENT_ONLY, - ContentCapturingMode.SPAN_AND_EVENT, - ): - return {} - - optional_attrs = ( - ( - GenAI.GEN_AI_INPUT_MESSAGES, - [asdict(m) for m in input_messages] if input_messages else None, - ), - ( - GenAI.GEN_AI_OUTPUT_MESSAGES, - [asdict(m) for m in output_messages] if output_messages else None, - ), - ( - GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, - [asdict(p) for p in system_instruction] - if system_instruction - else None, - ), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _maybe_emit_llm_event( - logger: Logger | None, - span: Span, - invocation: LLMInvocation, - error_type: str | None = None, -) -> None: - """Emit a gen_ai.client.inference.operation.details event to the logger. - - This function creates a LogRecord event following the semantic convention - for gen_ai.client.inference.operation.details as specified in the GenAI - event semantic conventions. - - For more details, see the semantic convention documentation: - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md#event-eventgen_aiclientinferenceoperationdetails - """ - if not is_experimental_mode() or not should_emit_event() or logger is None: - return - - # Build event attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_llm_common_attributes(invocation)) - attributes.update(_get_llm_request_attributes(invocation)) - attributes.update(_get_llm_response_attributes(invocation)) - attributes.update( - _get_llm_messages_attributes_for_event( - invocation.input_messages, - invocation.output_messages, - invocation.system_instruction, - ) - ) - - # Add error.type if operation ended in error - if error_type is not None: - attributes[error_attributes.ERROR_TYPE] = error_type - - # Create and emit the event - context = set_span_in_context(span, get_current()) - event = LogRecord( - event_name="gen_ai.client.inference.operation.details", - attributes=attributes, - context=context, - ) - logger.emit(event) - - -def _apply_llm_finish_attributes( - span: Span, invocation: LLMInvocation -) -> None: - """Apply attributes/messages common to finish() paths.""" - # Update span name - span.update_name(_get_llm_span_name(invocation)) - - # Build all attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_llm_common_attributes(invocation)) - attributes.update(_get_llm_request_attributes(invocation)) - attributes.update(_get_llm_response_attributes(invocation)) - attributes.update( - _get_messages_attributes_for_span( - invocation.input_messages, - invocation.output_messages, - invocation.system_instruction, - ) - ) - attributes.update(invocation.attributes) - - # Set all attributes on the span - if attributes: - span.set_attributes(attributes) - - -def _apply_embedding_finish_attributes( - span: Span, invocation: EmbeddingInvocation -) -> None: - """Apply attributes common to embedding finish() paths.""" - # Update span name - span.update_name(_get_embedding_span_name(invocation)) - - # Build all attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_embedding_common_attributes(invocation)) - attributes.update(_get_embedding_request_attributes(invocation)) - attributes.update(_get_embedding_response_attributes(invocation)) - - attributes.update(invocation.attributes) - - # Set all attributes on the span - if attributes: - span.set_attributes(attributes) - - -def _apply_error_attributes(span: Span, error: Error, error_type: str) -> None: - """Apply status and error attributes common to error() paths.""" - span.set_status(Status(StatusCode.ERROR, error.message)) - if span.is_recording(): - span.set_attribute(error_attributes.ERROR_TYPE, error_type) - - -def _get_llm_request_attributes( - invocation: LLMInvocation, -) -> dict[str, Any]: - """Get GenAI request semantic convention attributes.""" - optional_attrs = ( - (GenAI.GEN_AI_REQUEST_TEMPERATURE, invocation.temperature), - (GenAI.GEN_AI_REQUEST_TOP_P, invocation.top_p), - (GenAI.GEN_AI_REQUEST_FREQUENCY_PENALTY, invocation.frequency_penalty), - (GenAI.GEN_AI_REQUEST_PRESENCE_PENALTY, invocation.presence_penalty), - (GenAI.GEN_AI_REQUEST_MAX_TOKENS, invocation.max_tokens), - (GenAI.GEN_AI_REQUEST_STOP_SEQUENCES, invocation.stop_sequences), - (GenAI.GEN_AI_REQUEST_SEED, invocation.seed), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _get_embedding_request_attributes( - invocation: EmbeddingInvocation, -) -> dict[str, Any]: - """Get GenAI request semantic convention attributes.""" - optional_attrs = ( - (GenAI.GEN_AI_REQUEST_MODEL, invocation.request_model), - (GenAI.GEN_AI_EMBEDDINGS_DIMENSION_COUNT, invocation.dimension_count), - (GenAI.GEN_AI_REQUEST_ENCODING_FORMATS, invocation.encoding_formats), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _get_llm_response_attributes( - invocation: LLMInvocation, -) -> dict[str, Any]: - """Get GenAI response semantic convention attributes.""" - finish_reasons: list[str] | None - if invocation.finish_reasons is not None: - finish_reasons = invocation.finish_reasons - elif invocation.output_messages: - finish_reasons = [ - message.finish_reason - for message in invocation.output_messages - if message.finish_reason - ] - else: - finish_reasons = None - - # De-duplicate finish reasons - unique_finish_reasons = ( - sorted(set(finish_reasons)) if finish_reasons else None - ) - - optional_attrs = ( - ( - GenAI.GEN_AI_RESPONSE_FINISH_REASONS, - unique_finish_reasons if unique_finish_reasons else None, - ), - (GenAI.GEN_AI_RESPONSE_MODEL, invocation.response_model_name), - (GenAI.GEN_AI_RESPONSE_ID, invocation.response_id), - (GenAI.GEN_AI_USAGE_INPUT_TOKENS, invocation.input_tokens), - (GenAI.GEN_AI_USAGE_OUTPUT_TOKENS, invocation.output_tokens), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _apply_workflow_finish_attributes( - span: Span, invocation: WorkflowInvocation -) -> None: - """Apply attributes/messages common to finish() paths.""" - - # Build all attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_workflow_common_attributes(invocation)) - attributes.update( - _get_messages_attributes_for_span( - invocation.input_messages, - invocation.output_messages, - ) - ) - attributes.update(invocation.attributes) - - # Set all attributes on the span - if attributes: - span.set_attributes(attributes) - - -def _get_workflow_common_attributes( - invocation: WorkflowInvocation, -) -> dict[str, Any]: - """Get common Workflow attributes shared by finish() and error() paths. - - Returns a dictionary of attributes. - """ - return { - GenAI.GEN_AI_OPERATION_NAME: invocation.operation_name, - } - - -def _get_embedding_response_attributes( - invocation: EmbeddingInvocation, -) -> dict[str, Any]: - """Get GenAI response semantic convention attributes.""" - optional_attrs = ( - (GenAI.GEN_AI_RESPONSE_MODEL, invocation.response_model_name), - (GenAI.GEN_AI_USAGE_INPUT_TOKENS, invocation.input_tokens), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -__all__ = [ - "_apply_llm_finish_attributes", - "_apply_error_attributes", - "_get_llm_common_attributes", - "_get_llm_request_attributes", - "_get_llm_response_attributes", - "_get_llm_span_name", - "_maybe_emit_llm_event", - "_get_workflow_common_attributes", - "_apply_workflow_finish_attributes", - "_apply_embedding_finish_attributes", - "_get_embedding_common_attributes", - "_get_embedding_request_attributes", - "_get_embedding_response_attributes", - "_get_embedding_span_name", - "_get_workflow_span_name", -] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py index 6d59f03bf5e..103c168023b 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py @@ -14,20 +14,28 @@ from __future__ import annotations -from contextvars import Token -from dataclasses import dataclass, field +from dataclasses import dataclass from enum import Enum -from typing import Any, Literal, Type, Union +from typing import TYPE_CHECKING, Any, Literal, Type, Union -from typing_extensions import TypeAlias +if TYPE_CHECKING: + from opentelemetry.util.genai._inference_invocation import ( # pylint: disable=useless-import-alias + LLMInvocation as LLMInvocation, # noqa: PLC0414 + ) + from opentelemetry.util.genai._invocation import ( # pylint: disable=useless-import-alias + GenAIInvocation as GenAIInvocation, # noqa: PLC0414 + ) -from opentelemetry.context import Context -from opentelemetry.semconv._incubating.attributes import ( - gen_ai_attributes as GenAI, -) -from opentelemetry.trace import Span -ContextToken: TypeAlias = Token[Context] +class ContentCapturingMode(Enum): + # Do not capture content (default). + NO_CONTENT = 0 + # Only capture content in spans. + SPAN_ONLY = 1 + # Only capture content in events. + EVENT_ONLY = 2 + # Capture content in both spans and events. + SPAN_AND_EVENT = 3 @dataclass() @@ -41,23 +49,12 @@ class GenericPart: type: Literal["generic"] = "generic" -class ContentCapturingMode(Enum): - # Do not capture content (default). - NO_CONTENT = 0 - # Only capture content in spans. - SPAN_ONLY = 1 - # Only capture content in events. - EVENT_ONLY = 2 - # Capture content in both spans and events. - SPAN_AND_EVENT = 3 - - @dataclass() class ToolCallRequest: """Represents a tool call requested by the model (message part only). Use this for tool calls in message history. For execution tracking with spans - and metrics, use ToolCall instead. + and metrics, use ToolInvocation instead. This model is specified as part of semconv in `GenAI messages Python models - ToolCallRequestPart `__. @@ -84,7 +81,7 @@ class ToolCallResponse: @dataclass() class ServerToolCall: - """Represents a server-side tool call invocation. + """Represents a server-side tool call. Server tool calls are executed by the model provider on the server side rather than by the client application. Provider-specific tools (e.g., code_interpreter, @@ -238,187 +235,21 @@ class OutputMessage: finish_reason: str | FinishReason -def _new_input_messages() -> list[InputMessage]: - return [] - - -def _new_output_messages() -> list[OutputMessage]: - return [] - - -def _new_system_instruction() -> list[MessagePart]: - return [] - - -def _new_str_any_dict() -> dict[str, Any]: - return {} - - -@dataclass -class GenAIInvocation: - context_token: ContextToken | None = None - span: Span | None = None - attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) - error_type: str | None = None - - monotonic_start_s: float | None = None - """ - Monotonic start time in seconds (from timeit.default_timer) used for - duration calculations to avoid mixing clock sources. This is populated - by the TelemetryHandler when starting an invocation. - """ - - -@dataclass -class WorkflowInvocation(GenAIInvocation): - """ - Represents predetermined static sequence of operations eg: Agent, LLM, tool, and retrieval invocations. - A workflow groups multiple operations together, accepting input(s) and producing final output(s). - """ - - name: str = "" - operation_name: str = "invoke_workflow" - input_messages: list[InputMessage] = field( - default_factory=_new_input_messages - ) - output_messages: list[OutputMessage] = field( - default_factory=_new_output_messages - ) - - def __post_init__(self) -> None: - self.operation_name = "invoke_workflow" - - @dataclass -class LLMInvocation(GenAIInvocation): - """ - Represents a single LLM call invocation. When creating an LLMInvocation object, - only update the data attributes. The span and context_token attributes are - set by the TelemetryHandler. - """ - - operation_name: str = GenAI.GenAiOperationNameValues.CHAT.value - request_model: str | None = None - input_messages: list[InputMessage] = field( - default_factory=_new_input_messages - ) - output_messages: list[OutputMessage] = field( - default_factory=_new_output_messages - ) - system_instruction: list[MessagePart] = field( - default_factory=_new_system_instruction - ) - provider: str | None = None - response_model_name: str | None = None - response_id: str | None = None - finish_reasons: list[str] | None = None - input_tokens: int | None = None - output_tokens: int | None = None - attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) - """ - Additional attributes to set on spans and/or events. These attributes - will not be set on metrics. - """ - metric_attributes: dict[str, Any] = field( - default_factory=_new_str_any_dict - ) - """ - Additional attributes to set on metrics. Must be of a low cardinality. - These attributes will not be set on spans or events. - """ - temperature: float | None = None - top_p: float | None = None - frequency_penalty: float | None = None - presence_penalty: float | None = None - max_tokens: int | None = None - stop_sequences: list[str] | None = None - seed: int | None = None - server_address: str | None = None - server_port: int | None = None - - -@dataclass -class EmbeddingInvocation(GenAIInvocation): - """ - Represents a single embedding model invocation. When creating an - EmbeddingInvocation object, only update the data attributes. The span - and context_token attributes are set by the TelemetryHandler. - """ - - operation_name: str = GenAI.GenAiOperationNameValues.EMBEDDINGS.value - request_model: str | None = None - provider: str | None = None # e.g., azure.ai.openai, openai, aws.bedrock - server_address: str | None = None - server_port: int | None = None - - # encoding_formats can be multi-value -> combinational cardinality risk. - # Keep on spans/events only. - encoding_formats: list[str] | None = None - input_tokens: int | None = None - dimension_count: int | None = None - response_model_name: str | None = None - - attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) - """ - Additional attributes to set on spans and/or events. These attributes - will not be set on metrics. - """ - - metric_attributes: dict[str, Any] = field( - default_factory=_new_str_any_dict - ) - """ - Additional attributes to set on metrics. Must be of a low cardinality. - These attributes will not be set on spans or events. - """ - - -@dataclass() -class ToolCall(GenAIInvocation): - """Represents a tool call for execution tracking with spans and metrics. - - This type extends GenAIInvocation (like LLMInvocation) for consistent lifecycle - management across all invocation types. It is NOT used as a MessagePart directly - - use ToolCallRequest for that purpose. - - Inherits from GenAIInvocation: - - context_token: Context tracking for span lifecycle - - span: Active span reference - - attributes: Custom attributes dict for extensibility - - Reference: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md#execute-tool-span - - Semantic convention attributes for execute_tool spans: - - gen_ai.operation.name: "execute_tool" (Required) - - gen_ai.tool.name: Name of the tool (Recommended) - - gen_ai.tool.call.id: Tool call identifier (Recommended if available) - - gen_ai.tool.type: Type classification - "function", "extension", or "datastore" (Recommended if available) - - gen_ai.tool.description: Tool description (Recommended if available) - - gen_ai.tool.call.arguments: Parameters passed to tool (Opt-In, may contain sensitive data) - - gen_ai.tool.call.result: Result returned by tool (Opt-In, may contain sensitive data) - - error.type: Error type if operation failed (Conditionally Required) - """ - - # Message identification fields (same as ToolCallRequest) - # Note: These are required fields but must have defaults due to dataclass inheritance - name: str = "" - arguments: Any = None - id: str | None = None - type: Literal["tool_call"] = "tool_call" +class Error: + message: str + type: Type[BaseException] - # Execution tracking fields (used for execute_tool spans): - # gen_ai.tool.type - Tool type: "function", "extension", or "datastore" - tool_type: str | None = None - # gen_ai.tool.description - Description of what the tool does - tool_description: str | None = None - # gen_ai.tool.call.result - Result returned by the tool (Opt-In, may contain sensitive data) - tool_result: Any = None - # Timing field (not inherited from GenAIInvocation, matches LLMInvocation pattern) - monotonic_start_s: float | None = None +def __getattr__(name: str) -> object: + if name == "GenAIInvocation": + import opentelemetry.util.genai.invocation as _inv # noqa: PLC0415 # pylint: disable=import-outside-toplevel + return _inv.GenAIInvocation + if name == "LLMInvocation": + from opentelemetry.util.genai._inference_invocation import ( # noqa: PLC0415 # pylint: disable=import-outside-toplevel + LLMInvocation, + ) -@dataclass -class Error: - message: str - type: Type[BaseException] + return LLMInvocation + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/util/opentelemetry-util-genai/tests/test_handler_metrics.py b/util/opentelemetry-util-genai/tests/test_handler_metrics.py index b45383abfe7..8c758faea70 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_metrics.py +++ b/util/opentelemetry-util-genai/tests/test_handler_metrics.py @@ -9,7 +9,7 @@ from opentelemetry.semconv.schemas import Schemas from opentelemetry.test.test_base import TestBase from opentelemetry.util.genai.handler import TelemetryHandler -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import Error _DEFAULT_SCHEMA_URL = Schemas.V1_37_0.value @@ -22,19 +22,18 @@ def test_stop_llm_records_duration_and_tokens(self) -> None: tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, ) - invocation = LLMInvocation(request_model="model", provider="prov") - invocation.input_tokens = 5 - invocation.output_tokens = 7 # Patch default_timer during start to ensure monotonic_start_s with patch("timeit.default_timer", return_value=1000.0): - handler.start_llm(invocation) + invocation = handler.start_inference("prov", request_model="model") + invocation.input_tokens = 5 + invocation.output_tokens = 7 # Simulate 2 seconds of elapsed monotonic time (seconds) with patch( "timeit.default_timer", return_value=1002.0, ): - handler.stop_llm(invocation) + invocation.stop() self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -80,17 +79,19 @@ def test_stop_llm_records_duration_and_tokens_with_additional_attributes( meter_provider=self.meter_provider, ) - invocation = LLMInvocation(request_model="model", provider="prov") + invocation = handler.start_inference( + "prov", + request_model="model", + server_address="custom.server.com", + server_port=42, + ) invocation.input_tokens = 5 invocation.output_tokens = 7 - invocation.server_address = "custom.server.com" - invocation.server_port = 42 - handler.start_llm(invocation) invocation.metric_attributes = { "custom.attribute": "custom_value", } invocation.attributes = {"should not be on metrics": "value"} - handler.stop_llm(invocation) + invocation.stop() self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -115,18 +116,17 @@ def test_fail_llm_records_error_and_available_tokens(self) -> None: tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, ) - invocation = LLMInvocation(request_model="err-model", provider=None) - invocation.input_tokens = 11 # Patch default_timer during start to ensure monotonic_start_s with patch("timeit.default_timer", return_value=2000.0): - handler.start_llm(invocation) + invocation = handler.start_inference("", request_model="err-model") + invocation.input_tokens = 11 error = Error(message="boom", type=ValueError) with patch( "timeit.default_timer", return_value=2001.0, ): - handler.fail_llm(invocation, error) + invocation.fail(error) self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -162,7 +162,7 @@ def _harvest_metrics( resource_metrics is the raw ResourceMetrics list for scope-level assertions (e.g. schema_url). """ - metrics = self.get_sorted_metrics(SCOPE) + metrics = self.get_sorted_metrics() metrics_by_name: Dict[str, List[Any]] = {} for metric in metrics or []: points = metric.data.data_points or [] diff --git a/util/opentelemetry-util-genai/tests/test_handler_workflow.py b/util/opentelemetry-util-genai/tests/test_handler_workflow.py index d3af4e9ec75..3bf689a14b8 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_workflow.py +++ b/util/opentelemetry-util-genai/tests/test_handler_workflow.py @@ -13,15 +13,15 @@ from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAI, ) -from opentelemetry.trace import SpanKind +from opentelemetry.trace import INVALID_SPAN, SpanKind from opentelemetry.trace.status import StatusCode from opentelemetry.util.genai.handler import TelemetryHandler +from opentelemetry.util.genai.invocation import WorkflowInvocation from opentelemetry.util.genai.types import ( Error, InputMessage, OutputMessage, Text, - WorkflowInvocation, ) @@ -47,71 +47,55 @@ class TelemetryHandlerWorkflowTest(_WorkflowTestBase): # start_workflow # ------------------------------------------------------------------ - def test_operation_name_is_immutable(self) -> None: - invocation = WorkflowInvocation(name="wf", operation_name="custom_op") - self.assertEqual(invocation.operation_name, "invoke_workflow") - def test_start_workflow_creates_span(self) -> None: - invocation = WorkflowInvocation(name="my_workflow") - self.handler.start(invocation) - - self.assertIsNotNone(invocation.span) - self.assertIsNotNone(invocation.context_token) - self.assertIsNotNone(invocation.monotonic_start_s) - - # Clean up - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="my_workflow") + self.assertIsNot(invocation.span, INVALID_SPAN) + invocation.stop() def test_start_workflow_span_name(self) -> None: - invocation = WorkflowInvocation(name="my_pipeline") - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="my_pipeline") + invocation.stop() spans = self._get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual(spans[0].name, "invoke_workflow my_pipeline") def test_start_workflow_span_name_without_name(self) -> None: - invocation = WorkflowInvocation() - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name=None) + invocation.stop() spans = self._get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual(spans[0].name, "invoke_workflow") def test_start_workflow_span_kind_is_internal(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="wf") + invocation.stop() spans = self._get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual(spans[0].kind, SpanKind.INTERNAL) def test_start_workflow_records_monotonic_start(self) -> None: - invocation = WorkflowInvocation(name="wf") with patch("timeit.default_timer", return_value=500.0): - self.handler.start(invocation) - self.assertEqual(invocation.monotonic_start_s, 500.0) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="wf") + self.assertEqual(invocation._monotonic_start_s, 500.0) + invocation.stop() # ------------------------------------------------------------------ # stop_workflow # ------------------------------------------------------------------ def test_stop_workflow_ends_span(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="wf") + invocation.stop() spans = self._get_finished_spans() self.assertEqual(len(spans), 1) def test_stop_workflow_sets_operation_name_attribute(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="wf") + invocation.stop() spans = self._get_finished_spans() self.assertEqual( @@ -120,36 +104,27 @@ def test_stop_workflow_sets_operation_name_attribute(self) -> None: ) def test_stop_workflow_sets_custom_attributes(self) -> None: - invocation = WorkflowInvocation(name="wf") + invocation = self.handler.start_workflow(name="wf") invocation.attributes["custom.key"] = "custom_value" - self.handler.start(invocation) - self.handler.stop(invocation) + invocation.stop() spans = self._get_finished_spans() self.assertEqual(spans[0].attributes["custom.key"], "custom_value") - def test_stop_workflow_noop_when_not_started(self) -> None: - invocation = WorkflowInvocation(name="wf") - # Not started — span and context_token are None - result = self.handler.stop(invocation) - self.assertIs(result, invocation) - self.assertEqual(len(self._get_finished_spans()), 0) - def test_stop_workflow_returns_invocation(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - result = self.handler.stop(invocation) - self.assertIs(result, invocation) + invocation = self.handler.start_workflow(name="wf") + invocation.stop() + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) # ------------------------------------------------------------------ # fail_workflow # ------------------------------------------------------------------ def test_fail_workflow_sets_error_status(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) + invocation = self.handler.start_workflow(name="wf") error = Error(message="something broke", type=RuntimeError) - self.handler.fail(invocation, error) + invocation.fail(error) spans = self._get_finished_spans() self.assertEqual(len(spans), 1) @@ -157,19 +132,17 @@ def test_fail_workflow_sets_error_status(self) -> None: self.assertEqual(spans[0].status.description, "something broke") def test_fail_workflow_sets_error_type_attribute(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) + invocation = self.handler.start_workflow(name="wf") error = Error(message="bad", type=ValueError) - self.handler.fail(invocation, error) + invocation.fail(error) spans = self._get_finished_spans() self.assertEqual(spans[0].attributes["error.type"], "ValueError") def test_fail_workflow_sets_operation_name_attribute(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) + invocation = self.handler.start_workflow(name="wf") error = Error(message="fail", type=TypeError) - self.handler.fail(invocation, error) + invocation.fail(error) spans = self._get_finished_spans() self.assertEqual( @@ -177,19 +150,12 @@ def test_fail_workflow_sets_operation_name_attribute(self) -> None: "invoke_workflow", ) - def test_fail_workflow_noop_when_not_started(self) -> None: - invocation = WorkflowInvocation(name="wf") - error = Error(message="fail", type=RuntimeError) - result = self.handler.fail(invocation, error) - self.assertIs(result, invocation) - self.assertEqual(len(self._get_finished_spans()), 0) - - def test_fail_workflow_returns_invocation(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - error = Error(message="err", type=RuntimeError) - result = self.handler.fail(invocation, error) - self.assertIs(result, invocation) + def test_fail_workflow_ends_span(self) -> None: + invocation = self.handler.start_workflow(name="wf") + invocation.fail(Error(message="err", type=RuntimeError)) + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].status.status_code, StatusCode.ERROR) class TelemetryHandlerWorkflowContextManagerTest(_WorkflowTestBase): @@ -198,10 +164,8 @@ class TelemetryHandlerWorkflowContextManagerTest(_WorkflowTestBase): # ------------------------------------------------------------------ def test_workflow_context_manager_creates_and_ends_span(self) -> None: - invocation = WorkflowInvocation(name="ctx_wf") - with self.handler.workflow(invocation) as inv: - self.assertIsNotNone(inv.span) - self.assertIsNotNone(inv.context_token) + with self.handler.workflow(name="ctx_wf") as inv: + self.assertIsNot(inv.span, INVALID_SPAN) spans = self._get_finished_spans() self.assertEqual(len(spans), 1) @@ -210,30 +174,27 @@ def test_workflow_context_manager_creates_and_ends_span(self) -> None: def test_workflow_context_manager_default_invocation(self) -> None: with self.handler.workflow() as inv: self.assertIsInstance(inv, WorkflowInvocation) - self.assertEqual(inv.name, "") - self.assertEqual(inv.operation_name, "invoke_workflow") + self.assertIsNone(inv.name) + self.assertEqual(inv._operation_name, "invoke_workflow") spans = self._get_finished_spans() self.assertEqual(len(spans), 1) def test_workflow_context_manager_sets_attributes_on_span(self) -> None: - invocation = WorkflowInvocation(name="wf") - with self.handler.workflow(invocation) as inv: + with self.handler.workflow("wf") as inv: inv.attributes["my.attr"] = "hello" spans = self._get_finished_spans() self.assertEqual(spans[0].attributes["my.attr"], "hello") def test_workflow_context_manager_reraises_exception(self) -> None: - invocation = WorkflowInvocation(name="wf") with pytest.raises(ValueError, match="test error"): - with self.handler.workflow(invocation): + with self.handler.workflow("wf"): raise ValueError("test error") def test_workflow_context_manager_marks_error_on_exception(self) -> None: - invocation = WorkflowInvocation(name="wf") with pytest.raises(ValueError): - with self.handler.workflow(invocation): + with self.handler.workflow("wf"): raise ValueError("boom") spans = self._get_finished_spans() @@ -243,8 +204,7 @@ def test_workflow_context_manager_marks_error_on_exception(self) -> None: self.assertEqual(spans[0].attributes["error.type"], "ValueError") def test_workflow_context_manager_success_has_unset_status(self) -> None: - invocation = WorkflowInvocation(name="wf") - with self.handler.workflow(invocation): + with self.handler.workflow("wf"): pass spans = self._get_finished_spans() @@ -255,13 +215,9 @@ def test_workflow_context_manager_with_messages(self) -> None: out = OutputMessage( role="assistant", parts=[Text(content="hi")], finish_reason="stop" ) - invocation = WorkflowInvocation( - name="msg_wf", - input_messages=[inp], - output_messages=[out], - ) - with self.handler.workflow(invocation): - pass + with self.handler.workflow("msg_wf") as inv: + inv.input_messages = [inp] + inv.output_messages = [out] spans = self._get_finished_spans() self.assertEqual(len(spans), 1) @@ -269,42 +225,3 @@ def test_workflow_context_manager_with_messages(self) -> None: spans[0].attributes[GenAI.GEN_AI_OPERATION_NAME], "invoke_workflow", ) - - def test_workflow_context_manager_swallows_start_failure(self) -> None: - """workflow() should yield even if start_workflow raises.""" - invocation = WorkflowInvocation(name="wf") - with patch.object( - self.handler, - "start", - side_effect=RuntimeError("start failed"), - ): - # Should not raise — the exception is swallowed with a warning - with self.handler.workflow(invocation) as inv: - self.assertIs(inv, invocation) - - def test_workflow_context_manager_swallows_stop_failure(self) -> None: - """workflow() should not raise if stop_workflow fails.""" - invocation = WorkflowInvocation(name="wf") - with patch.object( - self.handler, - "stop", - side_effect=RuntimeError("stop failed"), - ): - # Should not raise - with self.handler.workflow(invocation): - pass - - def test_workflow_context_manager_swallows_fail_workflow_failure( - self, - ) -> None: - """workflow() should still re-raise the original exception even if - fail_workflow itself raises.""" - invocation = WorkflowInvocation(name="wf") - with patch.object( - self.handler, - "fail", - side_effect=RuntimeError("fail broke"), - ): - with pytest.raises(ValueError, match="original"): - with self.handler.workflow(invocation): - raise ValueError("original") diff --git a/util/opentelemetry-util-genai/tests/test_toolcall.py b/util/opentelemetry-util-genai/tests/test_toolcall.py index d076f5e72bc..abf7f637ae1 100644 --- a/util/opentelemetry-util-genai/tests/test_toolcall.py +++ b/util/opentelemetry-util-genai/tests/test_toolcall.py @@ -12,20 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Tests for ToolCallRequest and ToolCall inheritance structure""" +"""Tests for ToolCallRequest and ToolInvocation inheritance structure""" import pytest +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.util.genai.handler import TelemetryHandler +from opentelemetry.util.genai.invocation import GenAIInvocation from opentelemetry.util.genai.types import ( - GenAIInvocation, InputMessage, ServerToolCall, ServerToolCallResponse, - ToolCall, ToolCallRequest, ) +def _make_handler() -> TelemetryHandler: + return TelemetryHandler(tracer_provider=TracerProvider()) + + def test_toolcallrequest_is_message_part(): """ToolCallRequest is for message parts only""" tcr = ToolCallRequest( @@ -36,25 +41,40 @@ def test_toolcallrequest_is_message_part(): def test_toolcall_inherits_from_genaiinvocation(): - """ToolCall inherits from GenAIInvocation for lifecycle management""" - tc = ToolCall(name="get_weather", arguments={"city": "Paris"}) + """ToolInvocation inherits from GenAIInvocation for lifecycle management""" + handler = _make_handler() + tc = handler.start_tool("get_weather", arguments={"city": "Paris"}) assert isinstance(tc, GenAIInvocation) assert not isinstance(tc, ToolCallRequest) + tc.stop() def test_toolcall_has_attributes_dict(): - """ToolCall inherits attributes dict from GenAIInvocation""" - tc = ToolCall(name="test") + """ToolInvocation inherits attributes dict from GenAIInvocation""" + handler = _make_handler() + tc = handler.start_tool("test") tc.attributes["custom.key"] = "value" assert tc.attributes["custom.key"] == "value" + tc.stop() -def test_toolcall_in_message_part_union(): - """ToolCall can be used in messages despite not inheriting from ToolCallRequest""" - tc = ToolCall(name="get_weather", arguments={"city": "Paris"}) +def test_toolcallrequest_in_message_part_union(): + """ToolCallRequest (not ToolInvocation) is the correct type for message parts""" + tc = ToolCallRequest( + name="get_weather", arguments={"city": "Paris"}, id="call_123" + ) msg = InputMessage(role="assistant", parts=[tc]) assert len(msg.parts) == 1 - assert isinstance(msg.parts[0], GenAIInvocation) + assert isinstance(msg.parts[0], ToolCallRequest) + assert not isinstance(msg.parts[0], GenAIInvocation) + + +def test_toolcall_operation_name(): + """ToolInvocation operation_name is fixed to execute_tool""" + handler = _make_handler() + tc = handler.start_tool("my_tool") + assert tc._operation_name == "execute_tool" + tc.stop() def test_server_tool_call_basic(): diff --git a/util/opentelemetry-util-genai/tests/test_utils.py b/util/opentelemetry-util-genai/tests/test_utils.py index ee0e63d852d..31629c5b0c4 100644 --- a/util/opentelemetry-util-genai/tests/test_utils.py +++ b/util/opentelemetry-util-genai/tests/test_utils.py @@ -49,9 +49,7 @@ from opentelemetry.util.genai.handler import get_telemetry_handler from opentelemetry.util.genai.types import ( ContentCapturingMode, - EmbeddingInvocation, InputMessage, - LLMInvocation, MessagePart, OutputMessage, Text, @@ -248,25 +246,23 @@ def test_llm_start_and_stop_creates_span(self): # pylint: disable=no-self-use chat_generation = _create_output_message("hello back") system_instruction = _create_system_instruction() - with self.telemetry_handler.llm() as invocation: - for attr, value in { - "request_model": "test-model", - "input_messages": [message], - "system_instruction": system_instruction, - "provider": "test-provider", - "attributes": {"custom_attr": "value"}, - "temperature": 0.5, - "top_p": 0.9, - "stop_sequences": ["stop"], - "finish_reasons": ["stop"], - "response_model_name": "test-response-model", - "response_id": "response-id", - "input_tokens": 321, - "output_tokens": 654, - "server_address": "custom.server.com", - "server_port": 42, - }.items(): - setattr(invocation, attr, value) + with self.telemetry_handler.inference( + "test-provider", + request_model="test-model", + server_address="custom.server.com", + server_port=42, + ) as invocation: + invocation.input_messages = [message] + invocation.system_instruction = system_instruction + invocation.attributes = {"custom_attr": "value"} + invocation.temperature = 0.5 + invocation.top_p = 0.9 + invocation.stop_sequences = ["stop"] + invocation.finish_reasons = ["stop"] + invocation.response_model_name = "test-response-model" + invocation.response_id = "response-id" + invocation.input_tokens = 321 + invocation.output_tokens = 654 assert invocation.span is not None invocation.output_messages = [chat_generation] invocation.attributes.update({"extra": "info"}) @@ -331,18 +327,15 @@ def test_llm_manual_start_and_stop_creates_span(self): message = _create_input_message("hi") chat_generation = _create_output_message("ok") - invocation = LLMInvocation( - request_model="manual-model", - input_messages=[message], - provider="test-provider", - attributes={"manual": True}, + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="manual-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] + invocation.attributes["manual"] = True assert invocation.span is not None invocation.output_messages = [chat_generation] invocation.attributes.update({"extra_manual": "yes"}) - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) assert span.name == "chat manual-model" @@ -365,19 +358,16 @@ def test_llm_manual_start_and_stop_creates_span(self): ) def test_llm_span_finish_reasons_without_output_messages(self): - invocation = LLMInvocation( - request_model="model-without-output", - provider="test-provider", - finish_reasons=["length"], - response_model_name="alt-model", - response_id="resp-001", - input_tokens=12, - output_tokens=34, - ) - - self.telemetry_handler.start_llm(invocation) + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="model-without-output" + ) + invocation.finish_reasons = ["length"] + invocation.response_model_name = "alt-model" + invocation.response_id = "resp-001" + invocation.input_tokens = 12 + invocation.output_tokens = 34 assert invocation.span is not None - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) _assert_span_time_order(span) @@ -396,55 +386,46 @@ def test_llm_span_finish_reasons_without_output_messages(self): }, ) - def test_llm_span_finish_reasons_deduplicated_from_invocation(self): - invocation = LLMInvocation( - request_model="model-dedup", - provider="test-provider", - finish_reasons=["stop", "length", "stop"], + def test_llm_span_finish_reasons_from_invocation(self): + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="model-reasons" ) - - self.telemetry_handler.start_llm(invocation) + invocation.finish_reasons = ["stop", "length", "stop"] assert invocation.span is not None - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) attrs = _get_span_attributes(span) self.assertEqual( attrs[GenAI.GEN_AI_RESPONSE_FINISH_REASONS], - ("length", "stop"), + ("stop", "length", "stop"), ) - def test_llm_span_finish_reasons_deduplicated_from_output_messages(self): - invocation = LLMInvocation( - request_model="model-output-dedup", - provider="test-provider", + def test_llm_span_finish_reasons_from_output_messages(self): + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="model-output-reasons" ) - - self.telemetry_handler.start_llm(invocation) assert invocation.span is not None invocation.output_messages = [ _create_output_message("response-1", finish_reason="stop"), _create_output_message("response-2", finish_reason="length"), _create_output_message("response-3", finish_reason="stop"), ] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) attrs = _get_span_attributes(span) self.assertEqual( attrs[GenAI.GEN_AI_RESPONSE_FINISH_REASONS], - ("length", "stop"), + ("stop", "length", "stop"), ) def test_llm_span_uses_expected_schema_url(self): - invocation = LLMInvocation( - request_model="schema-model", - provider="schema-provider", + invocation = self.telemetry_handler.start_inference( + "schema-provider", request_model="schema-model" ) - - self.telemetry_handler.start_llm(invocation) assert invocation.span is not None - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) instrumentation = getattr(span, "instrumentation_scope", None) @@ -463,14 +444,11 @@ def test_llm_span_uses_expected_schema_url(self): emit_event="true", ) def test_llm_log_uses_expected_schema_url(self): - invocation = LLMInvocation( - request_model="schema-model", - provider="schema-provider", + invocation = self.telemetry_handler.start_inference( + "schema-provider", request_model="schema-model" ) - - self.telemetry_handler.start_llm(invocation) invocation.output_messages = [_create_output_message()] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() logs = self.log_exporter.get_finished_logs() self.assertEqual(len(logs), 1) @@ -487,20 +465,14 @@ def test_parent_child_span_relationship(self): message = _create_input_message("hi") chat_generation = _create_output_message("ok") - with self.telemetry_handler.llm() as parent_invocation: - for attr, value in { - "request_model": "parent-model", - "input_messages": [message], - "provider": "test-provider", - }.items(): - setattr(parent_invocation, attr, value) - with self.telemetry_handler.llm() as child_invocation: - for attr, value in { - "request_model": "child-model", - "input_messages": [message], - "provider": "test-provider", - }.items(): - setattr(child_invocation, attr, value) + with self.telemetry_handler.inference( + "test-provider", request_model="parent-model" + ) as parent_invocation: + parent_invocation.input_messages = [message] + with self.telemetry_handler.inference( + "test-provider", request_model="child-model" + ) as child_invocation: + child_invocation.input_messages = [message] # Stop child first by exiting inner context child_invocation.output_messages = [chat_generation] # Then stop parent by exiting outer context @@ -527,23 +499,18 @@ def test_parent_child_span_relationship(self): emit_event="", ) def test_embedding_parent_child_span_relationship(self): - parent_invocation = EmbeddingInvocation( - request_model="embed-parent-model", - provider="test-provider", - input_tokens=10, - ) - child_invocation = EmbeddingInvocation( - request_model="embed-child-model", - provider="test-provider", - input_tokens=5, + parent_invocation = self.telemetry_handler.start_embedding( + "test-provider", request_model="embed-parent-model" ) - - self.telemetry_handler.start(parent_invocation) + parent_invocation.input_tokens = 10 assert parent_invocation.span is not None - self.telemetry_handler.start(child_invocation) + child_invocation = self.telemetry_handler.start_embedding( + "test-provider", request_model="embed-child-model" + ) + child_invocation.input_tokens = 5 assert child_invocation.span is not None - self.telemetry_handler.stop(child_invocation) - self.telemetry_handler.stop(parent_invocation) + child_invocation.stop() + parent_invocation.stop() spans = self.span_exporter.get_finished_spans() assert len(spans) == 2 @@ -567,22 +534,17 @@ def test_embedding_parent_child_span_relationship(self): def test_llm_parent_embedding_child_span_relationship(self): message = _create_input_message("hi") chat_generation = _create_output_message("ok") - child_invocation = EmbeddingInvocation( - request_model="embed-child-model", - provider="test-provider", - input_tokens=3, - ) - with self.telemetry_handler.llm() as parent_invocation: - for attr, value in { - "request_model": "parent-model", - "input_messages": [message], - "provider": "test-provider", - }.items(): - setattr(parent_invocation, attr, value) - self.telemetry_handler.start(child_invocation) + with self.telemetry_handler.inference( + "test-provider", request_model="parent-model" + ) as parent_invocation: + parent_invocation.input_messages = [message] + child_invocation = self.telemetry_handler.start_embedding( + "test-provider", request_model="embed-child-model" + ) + child_invocation.input_tokens = 3 assert child_invocation.span is not None - self.telemetry_handler.stop(child_invocation) + child_invocation.stop() parent_invocation.output_messages = [chat_generation] spans = self.span_exporter.get_finished_spans() @@ -604,14 +566,12 @@ class BoomError(RuntimeError): pass message = _create_input_message("hi", role="user") - invocation = LLMInvocation( - request_model="test-model", - input_messages=[message], - provider="test-provider", - ) with self.assertRaises(BoomError): - with self.telemetry_handler.llm(invocation): + with self.telemetry_handler.inference( + "test-provider", request_model="test-model" + ) as invocation: + invocation.input_messages = [message] for attr, value in { "max_tokens": 128, "seed": 123, @@ -651,18 +611,16 @@ def test_embedding_context_manager_error_path_records_error_status_and_attrs( class BoomError(RuntimeError): pass - invocation = EmbeddingInvocation( - request_model="embed-model", - provider="test-provider", - dimension_count=1536, - input_tokens=7, - server_address="embed.example.com", - server_port=443, - attributes={"custom_embed_attr": "value"}, - ) - with self.assertRaises(BoomError): - with self.telemetry_handler.embedding(invocation): + with self.telemetry_handler.embedding( + "test-provider", + request_model="embed-model", + server_address="embed.example.com", + server_port=443, + ) as invocation: + invocation.dimension_count = 1536 + invocation.input_tokens = 7 + invocation.attributes["custom_embed_attr"] = "value" invocation.response_model_name = "embed-response-model" raise BoomError("embedding boom") @@ -692,22 +650,20 @@ class BoomError(RuntimeError): emit_event="", ) def test_embedding_manual_start_and_stop_creates_span(self): - invocation = EmbeddingInvocation( + invocation = self.telemetry_handler.start_embedding( + "test-provider", request_model="embed-model", - provider="test-provider", - dimension_count=1536, - encoding_formats=["float"], - input_tokens=123, server_address="custom.server.com", server_port=42, - attributes={"custom_embed_attr": "value"}, ) - - self.telemetry_handler.start(invocation) + invocation.dimension_count = 1536 + invocation.encoding_formats = ["float"] + invocation.input_tokens = 123 + invocation.attributes["custom_embed_attr"] = "value" assert invocation.span is not None invocation.attributes.update({"extra_embed": "info"}) invocation.metric_attributes = {"should not be on span": "value"} - self.telemetry_handler.stop(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) self.assertEqual(span.name, "embeddings embed-model") @@ -731,6 +687,23 @@ def test_embedding_manual_start_and_stop_creates_span(self): }, ) + def test_fail_with_exception_sets_error_status_and_type(self): + class BoomError(RuntimeError): + pass + + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="test-model" + ) + invocation.fail(BoomError("boom")) + + span = _get_single_span(self.span_exporter) + assert span.status.status_code == StatusCode.ERROR + assert span.status.description == "boom" + assert ( + _get_span_attributes(span)[error_attributes.ERROR_TYPE] + == BoomError.__qualname__ + ) + class AnyNonNone: def __eq__(self, other): diff --git a/util/opentelemetry-util-genai/tests/test_utils_events.py b/util/opentelemetry-util-genai/tests/test_utils_events.py index 20b3300c62c..7febea44c6a 100644 --- a/util/opentelemetry-util-genai/tests/test_utils_events.py +++ b/util/opentelemetry-util-genai/tests/test_utils_events.py @@ -30,7 +30,7 @@ ) from opentelemetry.semconv.attributes import error_attributes from opentelemetry.util.genai.handler import get_telemetry_handler -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import Error from .test_utils import ( _create_input_message, @@ -72,22 +72,19 @@ def tearDown(self): emit_event="true", ) def test_emits_llm_event(self): - invocation = LLMInvocation( - request_model="event-model", - input_messages=[_create_input_message("test query")], - system_instruction=_create_system_instruction(), - provider="test-provider", - temperature=0.7, - max_tokens=100, - response_model_name="response-model", - response_id="event-response-id", - input_tokens=10, - output_tokens=20, + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="event-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [_create_input_message("test query")] + invocation.system_instruction = _create_system_instruction() + invocation.temperature = 0.7 + invocation.max_tokens = 100 + invocation.response_model_name = "response-model" + invocation.response_id = "event-response-id" + invocation.input_tokens = 10 + invocation.output_tokens = 20 invocation.output_messages = [_create_output_message("test response")] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check that event was emitted logs = self.log_exporter.get_finished_logs() @@ -157,16 +154,13 @@ def test_emits_llm_event_and_span(self): chat_generation = _create_output_message("combined response") system_instruction = _create_system_instruction("System prompt here") - invocation = LLMInvocation( - request_model="combined-model", - input_messages=[message], - system_instruction=system_instruction, - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="combined-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] + invocation.system_instruction = system_instruction invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check span was created span = _get_single_span(self.span_exporter) @@ -217,15 +211,12 @@ class TestError(RuntimeError): pass message = _create_input_message("error test") - invocation = LLMInvocation( - request_model="error-model", - input_messages=[message], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="error-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] error = Error(message="Test error occurred", type=TestError) - self.telemetry_handler.fail_llm(invocation, error) + invocation.fail(error) # Check event was emitted logs = self.log_exporter.get_finished_logs() @@ -256,15 +247,12 @@ def test_does_not_emit_llm_event_when_emit_event_false(self): message = _create_input_message("emit false test") chat_generation = _create_output_message("emit false response") - invocation = LLMInvocation( - request_model="emit-false-model", - input_messages=[message], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="emit-false-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check no event was emitted logs = self.log_exporter.get_finished_logs() @@ -277,17 +265,14 @@ def test_does_not_emit_llm_event_when_emit_event_false(self): ) def test_does_not_emit_llm_event_by_default_for_no_content(self): """Test that event is not emitted by default when content_capturing is NO_CONTENT and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="default-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [_create_input_message("default test")] invocation.output_messages = [ _create_output_message("default response") ] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check that no event was emitted (NO_CONTENT defaults to False) logs = self.log_exporter.get_finished_logs() @@ -300,17 +285,14 @@ def test_does_not_emit_llm_event_by_default_for_no_content(self): ) def test_does_not_emit_llm_event_by_default_for_span_only(self): """Test that event is not emitted by default when content_capturing is SPAN_ONLY and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="default-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [_create_input_message("default test")] invocation.output_messages = [ _create_output_message("default response") ] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check that no event was emitted (SPAN_ONLY defaults to False) logs = self.log_exporter.get_finished_logs() @@ -323,17 +305,14 @@ def test_does_not_emit_llm_event_by_default_for_span_only(self): ) def test_emits_llm_event_by_default_for_event_only(self): """Test that event is emitted by default when content_capturing is EVENT_ONLY and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="default-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [_create_input_message("default test")] invocation.output_messages = [ _create_output_message("default response") ] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check that event was emitted (EVENT_ONLY defaults to True) logs = self.log_exporter.get_finished_logs() @@ -354,16 +333,13 @@ def test_emits_llm_event_by_default_for_span_and_event(self): chat_generation = _create_output_message("span and event response") system_instruction = _create_system_instruction("System prompt") - invocation = LLMInvocation( - request_model="span-and-event-model", - input_messages=[message], - system_instruction=system_instruction, - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="span-and-event-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] + invocation.system_instruction = system_instruction invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check span was created span = _get_single_span(self.span_exporter) diff --git a/util/opentelemetry-util-genai/tests/test_workflow_invocation.py b/util/opentelemetry-util-genai/tests/test_workflow_invocation.py index b9c0e756dac..3a80f1c214a 100644 --- a/util/opentelemetry-util-genai/tests/test_workflow_invocation.py +++ b/util/opentelemetry-util-genai/tests/test_workflow_invocation.py @@ -1,29 +1,50 @@ +import unittest + +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) +from opentelemetry.trace import INVALID_SPAN +from opentelemetry.util.genai.handler import TelemetryHandler from opentelemetry.util.genai.types import ( InputMessage, OutputMessage, Text, - WorkflowInvocation, ) -class TestWorkflowInvocation: # pylint: disable=no-self-use +class TestWorkflowInvocation(unittest.TestCase): + def setUp(self): + self.span_exporter = InMemorySpanExporter() + tracer_provider = TracerProvider() + tracer_provider.add_span_processor( + SimpleSpanProcessor(self.span_exporter) + ) + self.handler = TelemetryHandler(tracer_provider=tracer_provider) + def test_default_values(self): - invocation = WorkflowInvocation() - assert invocation.name == "" - assert invocation.operation_name == "invoke_workflow" + invocation = self.handler.start_workflow(name=None) + invocation.stop() + assert invocation.name is None + assert invocation._operation_name == "invoke_workflow" assert not invocation.input_messages assert not invocation.output_messages - assert invocation.span is None - assert invocation.context_token is None + assert invocation.span is not INVALID_SPAN assert not invocation.attributes def test_custom_name(self): - invocation = WorkflowInvocation(name="customer_support_pipeline") + invocation = self.handler.start_workflow( + name="customer_support_pipeline" + ) + invocation.stop() assert invocation.name == "customer_support_pipeline" def test_with_input_messages(self): msg = InputMessage(role="user", parts=[Text(content="hello")]) - invocation = WorkflowInvocation(input_messages=[msg]) + invocation = self.handler.start_workflow(name="test") + invocation.input_messages = [msg] + invocation.stop() assert len(invocation.input_messages) == 1 assert invocation.input_messages[0].role == "user" @@ -31,26 +52,36 @@ def test_with_output_messages(self): msg = OutputMessage( role="assistant", parts=[Text(content="hi")], finish_reason="stop" ) - invocation = WorkflowInvocation(output_messages=[msg]) + invocation = self.handler.start_workflow(name="test") + invocation.output_messages = [msg] + invocation.stop() assert len(invocation.output_messages) == 1 assert invocation.output_messages[0].finish_reason == "stop" def test_inherits_genai_invocation(self): - invocation = WorkflowInvocation(attributes={"key": "value"}) - assert invocation.attributes == {"key": "value"} + invocation = self.handler.start_workflow(name="test") + invocation.attributes["key"] = "value" + invocation.stop() + spans = self.span_exporter.get_finished_spans() + assert spans[0].attributes is not None + assert spans[0].attributes["key"] == "value" def test_default_lists_are_independent(self): - """Ensure default factory creates separate list instances.""" - inv1 = WorkflowInvocation() - inv2 = WorkflowInvocation() + """Ensure separate invocations get separate list instances.""" + inv1 = self.handler.start_workflow(name=None) + inv2 = self.handler.start_workflow(name=None) inv1.input_messages.append(InputMessage(role="user", parts=[])) assert len(inv2.input_messages) == 0 + inv1.stop() + inv2.stop() def test_default_attributes_are_independent(self): - inv1 = WorkflowInvocation() - inv2 = WorkflowInvocation() + inv1 = self.handler.start_workflow(name=None) + inv2 = self.handler.start_workflow(name=None) inv1.attributes["foo"] = "bar" assert "foo" not in inv2.attributes + inv1.stop() + inv2.stop() def test_full_construction(self): inp = InputMessage(role="user", parts=[Text(content="query")]) @@ -59,12 +90,10 @@ def test_full_construction(self): parts=[Text(content="answer")], finish_reason="stop", ) - invocation = WorkflowInvocation( - name="my_workflow", - operation_name="invoke_workflow", - input_messages=[inp], - output_messages=[out], - ) + invocation = self.handler.start_workflow(name="my_workflow") + invocation.input_messages = [inp] + invocation.output_messages = [out] + invocation.stop() assert invocation.name == "my_workflow" assert len(invocation.input_messages) == 1 assert len(invocation.output_messages) == 1 From 54c5ab487b4f5043a2279988bd21831dea9eea41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 07:59:48 +0000 Subject: [PATCH 68/78] build(deps): bump aiohttp from 3.13.3 to 3.13.4 (#4386) --- updated-dependencies: - dependency-name: aiohttp dependency-version: 3.13.4 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-requirements.txt b/docs-requirements.txt index 04c5e2eb62b..8f743798bc5 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -17,7 +17,7 @@ fsspec>=2025.9.0 # Required by instrumentation and exporter packages aio_pika~=7.2.0 -aiohttp~=3.0 +aiohttp~=3.13 aiokafka~=0.11.0 aiopg>=0.13.0,<1.3.0 asyncpg>=0.12.0 From 8c04ac5684b2a58abd24925e49f5966e8be2533a Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Mon, 13 Apr 2026 15:28:16 +0200 Subject: [PATCH 69/78] Revert "Build list of required jobs in generate-workflow (#4326)" (#4413) This reverts commit 22879d6b9fd252dcf5a77ec229e497105717d9b4. Now that we have just one job to check we don't need to build the list anymore. --- .github/workflows/generate_required_checks.py | 42 ------------------- .gitignore | 3 -- tox.ini | 1 - 3 files changed, 46 deletions(-) delete mode 100644 .github/workflows/generate_required_checks.py diff --git a/.github/workflows/generate_required_checks.py b/.github/workflows/generate_required_checks.py deleted file mode 100644 index 8e9185f76ec..00000000000 --- a/.github/workflows/generate_required_checks.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -This script builds a text file with the list of required checks based on -the tox environments. Similarly to the system we are using to build the -github workflows. -The output is in the format than can be cut-and-pasted into the python-contrib -terraform configuration in the admin repository. -""" - -from pathlib import Path - -from generate_workflows_lib import ( - get_lint_job_datas, - get_misc_job_datas, - get_test_job_datas, - get_tox_envs, -) - -tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini") - - -def get_gh_contexts_from_jobs(job_datas): - def get_job_name(job): - if isinstance(job, str): - return job - return job["ui_name"] - - return [ - f""" {{ context = "{get_job_name(job)}" }},\n""" - for job in job_datas - ] - - -jobs = sorted( - get_gh_contexts_from_jobs(get_lint_job_datas(get_tox_envs(tox_ini_path))) - + get_gh_contexts_from_jobs( - get_test_job_datas(get_tox_envs(tox_ini_path), ["ubuntu-latest"]) - ) - + get_gh_contexts_from_jobs(get_misc_job_datas(get_tox_envs(tox_ini_path))) -) -with open("opentelemetry-admin-jobs.txt", "w") as f: - for job in jobs: - f.write(job) diff --git a/.gitignore b/.gitignore index 09141b12eb4..1c32b4446a9 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,3 @@ target # Benchmark result files *-benchmark.json - -# opentelemetry-admin jobs -opentelemetry-admin-jobs.txt diff --git a/tox.ini b/tox.ini index 5b13ed9365a..8d8d86305b7 100644 --- a/tox.ini +++ b/tox.ini @@ -1124,7 +1124,6 @@ deps = commands = python {toxinidir}/.github/workflows/generate_workflows.py - python {toxinidir}/.github/workflows/generate_required_checks.py [testenv:shellcheck] From bf31c1d8aa6a1b7c9f0fb4ac00a790f2ece88a79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Em=C3=ADdio=20Neto?= <9735060+emdneto@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:14:13 -0300 Subject: [PATCH 70/78] Drop Python 3.9 support (#4412) * Drop Python 3.9 support Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * generate-workflows Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fixes Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * remove extra reference to pypy310 Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * changelog Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix flask tests Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix google-genai tests Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix google-genai tests Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * fix Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> * remove unused _ensure_gzip_single_response Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --------- Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- .github/ISSUE_TEMPLATE/bug_report.yaml | 8 +- .github/workflows/core_contrib_test.yml | 1102 ++++--- .../generate_workflows_lib/pyproject.toml | 3 +- .../src/generate_workflows_lib/__init__.py | 6 +- .../core_contrib_test.yml.j2 | 4 +- .../package-prepare-patch-release.yml | 4 +- .github/workflows/package-prepare-release.yml | 8 +- .github/workflows/package-release.yml | 2 +- .github/workflows/prepare-patch-release.yml | 4 +- .github/workflows/prepare-release-branch.yml | 8 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2932 +++-------------- .pylintrc | 10 +- CHANGELOG.md | 9 +- _template/pyproject.toml | 3 +- dev-requirements.txt | 3 +- .../pyproject.toml | 3 +- .../example/Dockerfile | 2 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_async_wrappers.py | 6 +- .../pyproject.toml | 4 +- .../tests/generate_content/test_e2e.py | 51 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_response_wrappers.py | 6 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_instrumentation.py | 41 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_asyncio_anext.py | 5 - .../pyproject.toml | 3 +- .../tests/test_asyncpg_wrapper.py | 2 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../tests/test_botocore_lambda.py | 2 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../test-requirements-0.txt | 1 + .../test-requirements-2.txt | 1 - .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../instrumentation/flask/__init__.py | 11 +- .../tests/test_flask_compatibility.py | 5 - .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../test-requirements.latest.txt | 21 +- .../test-requirements.oldest.txt | 14 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../opentelemetry-opamp-client/pyproject.toml | 3 +- .../test-requirements.latest.txt | 9 +- .../test-requirements.lowest.txt | 9 +- .../tests/opamp/test_e2e.py | 9 - .../pyproject.toml | 3 +- opentelemetry-distro/pyproject.toml | 3 +- opentelemetry-instrumentation/pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- pyproject.toml | 6 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- .../pyproject.toml | 3 +- tox.ini | 171 +- util/opentelemetry-util-genai/pyproject.toml | 3 +- util/opentelemetry-util-http/pyproject.toml | 3 +- 107 files changed, 1266 insertions(+), 3431 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 5265ebb3f96..1695f77f84a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -8,8 +8,8 @@ body: value: | Thanks for taking the time to fill out this bug report! Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage and track down your bug as quickly as possible. - Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-python-contrib/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug) to see if your bug is already addressed. - + Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-python-contrib/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug) to see if your bug is already addressed. + - type: textarea id: environment attributes: @@ -18,9 +18,9 @@ body: Please describe any aspect of your environment relevant to the problem, including your Python version, [platform](https://docs.python.org/3/library/platform.html), version numbers of installed dependencies, information about your cloud hosting provider, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main. value: | OS: (e.g, Ubuntu) - Python version: (e.g., Python 3.9.10) + Python version: (e.g., Python 3.10.0) Package version: (e.g., 0.46.0) - + - type: textarea attributes: label: What happened? diff --git a/.github/workflows/core_contrib_test.yml b/.github/workflows/core_contrib_test.yml index 4653f3d360f..d9f90d57d89 100644 --- a/.github/workflows/core_contrib_test.yml +++ b/.github/workflows/core_contrib_test.yml @@ -27,7 +27,7 @@ env: jobs: - py39-test-instrumentation-openai-v2-oldest: + py310-test-instrumentation-openai-v2-oldest: name: instrumentation-openai-v2-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -45,19 +45,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-oldest -- -ra + run: tox -e py310-test-instrumentation-openai-v2-oldest -- -ra - py39-test-instrumentation-openai-v2-latest: + py310-test-instrumentation-openai-v2-latest: name: instrumentation-openai-v2-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -75,19 +75,79 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-latest -- -ra + run: tox -e py310-test-instrumentation-openai-v2-latest -- -ra - py39-test-instrumentation-vertexai-oldest: + py310-test-instrumentation-openai_agents-v2-oldest: + name: instrumentation-openai_agents-v2-oldest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-openai_agents-v2-oldest -- -ra + + py310-test-instrumentation-openai_agents-v2-latest: + name: instrumentation-openai_agents-v2-latest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-openai_agents-v2-latest -- -ra + + py310-test-instrumentation-vertexai-oldest: name: instrumentation-vertexai-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -105,19 +165,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-oldest -- -ra + run: tox -e py310-test-instrumentation-vertexai-oldest -- -ra - py39-test-instrumentation-vertexai-latest: + py310-test-instrumentation-vertexai-latest: name: instrumentation-vertexai-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -135,19 +195,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-latest -- -ra + run: tox -e py310-test-instrumentation-vertexai-latest -- -ra - py39-test-instrumentation-google-genai-oldest: + py310-test-instrumentation-google-genai-oldest: name: instrumentation-google-genai-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -165,19 +225,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-oldest -- -ra + run: tox -e py310-test-instrumentation-google-genai-oldest -- -ra - py39-test-instrumentation-google-genai-latest: + py310-test-instrumentation-google-genai-latest: name: instrumentation-google-genai-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -195,19 +255,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-latest -- -ra + run: tox -e py310-test-instrumentation-google-genai-latest -- -ra - py39-test-instrumentation-anthropic-oldest: + py310-test-instrumentation-anthropic-oldest: name: instrumentation-anthropic-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -225,19 +285,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-oldest -- -ra + run: tox -e py310-test-instrumentation-anthropic-oldest -- -ra - py39-test-instrumentation-anthropic-latest: + py310-test-instrumentation-anthropic-latest: name: instrumentation-anthropic-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -255,19 +315,79 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-latest -- -ra + run: tox -e py310-test-instrumentation-anthropic-latest -- -ra + + py310-test-instrumentation-claude-agent-sdk-oldest: + name: instrumentation-claude-agent-sdk-oldest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python - py39-test-resource-detector-containerid: + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-claude-agent-sdk-oldest -- -ra + + py310-test-instrumentation-claude-agent-sdk-latest: + name: instrumentation-claude-agent-sdk-latest + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-claude-agent-sdk-latest -- -ra + + py310-test-resource-detector-containerid: name: resource-detector-containerid runs-on: ubuntu-latest timeout-minutes: 30 @@ -285,19 +405,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-resource-detector-containerid -- -ra + run: tox -e py310-test-resource-detector-containerid -- -ra - py39-test-resource-detector-azure-0: + py310-test-resource-detector-azure-0: name: resource-detector-azure-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -315,19 +435,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-resource-detector-azure-0 -- -ra + run: tox -e py310-test-resource-detector-azure-0 -- -ra - py39-test-resource-detector-azure-1: + py310-test-resource-detector-azure-1: name: resource-detector-azure-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -345,19 +465,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-resource-detector-azure-1 -- -ra + run: tox -e py310-test-resource-detector-azure-1 -- -ra - py39-test-sdk-extension-aws-0: + py310-test-sdk-extension-aws-0: name: sdk-extension-aws-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -375,19 +495,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-sdk-extension-aws-0 -- -ra + run: tox -e py310-test-sdk-extension-aws-0 -- -ra - py39-test-sdk-extension-aws-1: + py310-test-sdk-extension-aws-1: name: sdk-extension-aws-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -405,19 +525,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-sdk-extension-aws-1 -- -ra + run: tox -e py310-test-sdk-extension-aws-1 -- -ra - py39-test-distro: + py310-test-distro: name: distro runs-on: ubuntu-latest timeout-minutes: 30 @@ -435,19 +555,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-distro -- -ra + run: tox -e py310-test-distro -- -ra - py39-test-opentelemetry-instrumentation-wrapt1: + py310-test-opentelemetry-instrumentation-wrapt1: name: opentelemetry-instrumentation-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -465,19 +585,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt1 -- -ra + run: tox -e py310-test-opentelemetry-instrumentation-wrapt1 -- -ra - py39-test-opentelemetry-instrumentation-wrapt2: + py310-test-opentelemetry-instrumentation-wrapt2: name: opentelemetry-instrumentation-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -495,19 +615,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt2 -- -ra + run: tox -e py310-test-opentelemetry-instrumentation-wrapt2 -- -ra - py39-test-instrumentation-aiohttp-client: + py310-test-instrumentation-aiohttp-client: name: instrumentation-aiohttp-client runs-on: ubuntu-latest timeout-minutes: 30 @@ -525,19 +645,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-client -- -ra + run: tox -e py310-test-instrumentation-aiohttp-client -- -ra - py39-test-instrumentation-aiohttp-server: + py310-test-instrumentation-aiohttp-server: name: instrumentation-aiohttp-server runs-on: ubuntu-latest timeout-minutes: 30 @@ -555,19 +675,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-server -- -ra + run: tox -e py310-test-instrumentation-aiohttp-server -- -ra - py39-test-instrumentation-aiopg-wrapt1: + py310-test-instrumentation-aiopg-wrapt1: name: instrumentation-aiopg-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -585,19 +705,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-aiopg-wrapt1 -- -ra - py39-test-instrumentation-aiopg-wrapt2: + py310-test-instrumentation-aiopg-wrapt2: name: instrumentation-aiopg-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -615,19 +735,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-aiopg-wrapt2 -- -ra - py39-test-instrumentation-aws-lambda: + py310-test-instrumentation-aws-lambda: name: instrumentation-aws-lambda runs-on: ubuntu-latest timeout-minutes: 30 @@ -645,19 +765,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aws-lambda -- -ra + run: tox -e py310-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-botocore-0-wrapt1: + py310-test-instrumentation-botocore-0-wrapt1: name: instrumentation-botocore-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -675,19 +795,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-botocore-0-wrapt1 -- -ra - py39-test-instrumentation-botocore-0-wrapt2: + py310-test-instrumentation-botocore-0-wrapt2: name: instrumentation-botocore-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -705,19 +825,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-botocore-0-wrapt2 -- -ra - py39-test-instrumentation-botocore-1-wrapt1: + py310-test-instrumentation-botocore-1-wrapt1: name: instrumentation-botocore-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -735,19 +855,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-botocore-1-wrapt1 -- -ra - py39-test-instrumentation-botocore-1-wrapt2: + py310-test-instrumentation-botocore-1-wrapt2: name: instrumentation-botocore-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -765,19 +885,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-botocore-1-wrapt2 -- -ra - py39-test-instrumentation-botocore-2: + py310-test-instrumentation-botocore-2: name: instrumentation-botocore-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -795,19 +915,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-2 -- -ra + run: tox -e py310-test-instrumentation-botocore-2 -- -ra - py39-test-instrumentation-botocore-3: + py310-test-instrumentation-botocore-3: name: instrumentation-botocore-3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -825,19 +945,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-botocore-3 -- -ra + run: tox -e py310-test-instrumentation-botocore-3 -- -ra - py39-test-instrumentation-boto3sqs: + py310-test-instrumentation-boto3sqs: name: instrumentation-boto3sqs runs-on: ubuntu-latest timeout-minutes: 30 @@ -855,19 +975,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-boto3sqs -- -ra + run: tox -e py310-test-instrumentation-boto3sqs -- -ra - py39-test-instrumentation-django-0: + py310-test-instrumentation-django-0: name: instrumentation-django-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -885,19 +1005,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-0 -- -ra + run: tox -e py310-test-instrumentation-django-0 -- -ra - py39-test-instrumentation-django-1: + py310-test-instrumentation-django-1: name: instrumentation-django-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -915,19 +1035,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-1 -- -ra + run: tox -e py310-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-django-2: + py310-test-instrumentation-django-2: name: instrumentation-django-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -945,19 +1065,49 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "x64" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py310-test-instrumentation-django-2 -- -ra + + py310-test-instrumentation-django-3: + name: instrumentation-django-3 + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python-contrib + ref: ${{ env.CONTRIB_REPO_SHA }} + + - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }} + uses: actions/checkout@v4 + with: + repository: open-telemetry/opentelemetry-python + ref: ${{ env.CORE_REPO_SHA }} + path: opentelemetry-python + + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-2 -- -ra + run: tox -e py310-test-instrumentation-django-3 -- -ra - py39-test-instrumentation-dbapi-wrapt1: + py310-test-instrumentation-dbapi-wrapt1: name: instrumentation-dbapi-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -975,19 +1125,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-dbapi-wrapt1 -- -ra - py39-test-instrumentation-dbapi-wrapt2: + py310-test-instrumentation-dbapi-wrapt2: name: instrumentation-dbapi-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1005,19 +1155,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-dbapi-wrapt2 -- -ra - py39-test-instrumentation-asyncclick: + py310-test-instrumentation-asyncclick: name: instrumentation-asyncclick runs-on: ubuntu-latest timeout-minutes: 30 @@ -1035,19 +1185,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncclick -- -ra + run: tox -e py310-test-instrumentation-asyncclick -- -ra - py39-test-instrumentation-click: + py310-test-instrumentation-click: name: instrumentation-click runs-on: ubuntu-latest timeout-minutes: 30 @@ -1065,19 +1215,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-click -- -ra + run: tox -e py310-test-instrumentation-click -- -ra - py39-test-instrumentation-elasticsearch-0: + py310-test-instrumentation-elasticsearch-0: name: instrumentation-elasticsearch-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1095,19 +1245,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-0 -- -ra - py39-test-instrumentation-elasticsearch-1: + py310-test-instrumentation-elasticsearch-1: name: instrumentation-elasticsearch-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1125,19 +1275,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-1 -- -ra - py39-test-instrumentation-elasticsearch-2: + py310-test-instrumentation-elasticsearch-2: name: instrumentation-elasticsearch-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1155,20 +1305,20 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra + run: tox -e py310-test-instrumentation-elasticsearch-2 -- -ra - py39-test-instrumentation-falcon-0: - name: instrumentation-falcon-0 + py310-test-instrumentation-falcon-1: + name: instrumentation-falcon-1 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1185,20 +1335,20 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra + run: tox -e py310-test-instrumentation-falcon-1 -- -ra - py39-test-instrumentation-falcon-1: - name: instrumentation-falcon-1 + py310-test-instrumentation-falcon-2: + name: instrumentation-falcon-2 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1215,20 +1365,20 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra + run: tox -e py310-test-instrumentation-falcon-2 -- -ra - py39-test-instrumentation-falcon-2: - name: instrumentation-falcon-2 + py310-test-instrumentation-falcon-3: + name: instrumentation-falcon-3 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1245,20 +1395,20 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-2 -- -ra + run: tox -e py310-test-instrumentation-falcon-3 -- -ra - py39-test-instrumentation-falcon-3: - name: instrumentation-falcon-3 + py310-test-instrumentation-falcon-4: + name: instrumentation-falcon-4 runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -1275,19 +1425,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-falcon-3 -- -ra + run: tox -e py310-test-instrumentation-falcon-4 -- -ra - py39-test-instrumentation-fastapi: + py310-test-instrumentation-fastapi: name: instrumentation-fastapi runs-on: ubuntu-latest timeout-minutes: 30 @@ -1305,19 +1455,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-fastapi -- -ra + run: tox -e py310-test-instrumentation-fastapi -- -ra - py39-test-instrumentation-flask-0: + py310-test-instrumentation-flask-0: name: instrumentation-flask-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1335,19 +1485,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-0 -- -ra + run: tox -e py310-test-instrumentation-flask-0 -- -ra - py39-test-instrumentation-flask-1: + py310-test-instrumentation-flask-1: name: instrumentation-flask-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1365,19 +1515,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-1 -- -ra + run: tox -e py310-test-instrumentation-flask-1 -- -ra - py39-test-instrumentation-flask-2: + py310-test-instrumentation-flask-2: name: instrumentation-flask-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1395,19 +1545,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-2 -- -ra + run: tox -e py310-test-instrumentation-flask-2 -- -ra - py39-test-instrumentation-flask-3: + py310-test-instrumentation-flask-3: name: instrumentation-flask-3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1425,19 +1575,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-flask-3 -- -ra + run: tox -e py310-test-instrumentation-flask-3 -- -ra - py39-test-instrumentation-urllib: + py310-test-instrumentation-urllib: name: instrumentation-urllib runs-on: ubuntu-latest timeout-minutes: 30 @@ -1455,19 +1605,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib -- -ra + run: tox -e py310-test-instrumentation-urllib -- -ra - py39-test-instrumentation-urllib3-0: + py310-test-instrumentation-urllib3-0: name: instrumentation-urllib3-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1485,19 +1635,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-urllib3-1: + py310-test-instrumentation-urllib3-1: name: instrumentation-urllib3-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1515,19 +1665,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - py39-test-instrumentation-requests: + py310-test-instrumentation-requests: name: instrumentation-requests runs-on: ubuntu-latest timeout-minutes: 30 @@ -1545,19 +1695,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-requests -- -ra + run: tox -e py310-test-instrumentation-requests -- -ra - py39-test-instrumentation-starlette-oldest: + py310-test-instrumentation-starlette-oldest: name: instrumentation-starlette-oldest runs-on: ubuntu-latest timeout-minutes: 30 @@ -1575,19 +1725,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-starlette-oldest -- -ra + run: tox -e py310-test-instrumentation-starlette-oldest -- -ra - py39-test-instrumentation-starlette-latest: + py310-test-instrumentation-starlette-latest: name: instrumentation-starlette-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -1605,19 +1755,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-starlette-latest -- -ra + run: tox -e py310-test-instrumentation-starlette-latest -- -ra - py39-test-instrumentation-jinja2: + py310-test-instrumentation-jinja2: name: instrumentation-jinja2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1635,19 +1785,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-jinja2 -- -ra + run: tox -e py310-test-instrumentation-jinja2 -- -ra - py39-test-instrumentation-logging: + py310-test-instrumentation-logging: name: instrumentation-logging runs-on: ubuntu-latest timeout-minutes: 30 @@ -1665,19 +1815,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-logging -- -ra + run: tox -e py310-test-instrumentation-logging -- -ra - py39-test-exporter-richconsole: + py310-test-exporter-richconsole: name: exporter-richconsole runs-on: ubuntu-latest timeout-minutes: 30 @@ -1695,19 +1845,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-richconsole -- -ra + run: tox -e py310-test-exporter-richconsole -- -ra - py39-test-exporter-prometheus-remote-write: + py310-test-exporter-prometheus-remote-write: name: exporter-prometheus-remote-write runs-on: ubuntu-latest timeout-minutes: 30 @@ -1725,19 +1875,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-prometheus-remote-write -- -ra + run: tox -e py310-test-exporter-prometheus-remote-write -- -ra - py39-test-instrumentation-mysql-0: + py310-test-instrumentation-mysql-0: name: instrumentation-mysql-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1755,19 +1905,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysql-0 -- -ra + run: tox -e py310-test-instrumentation-mysql-0 -- -ra - py39-test-instrumentation-mysql-1: + py310-test-instrumentation-mysql-1: name: instrumentation-mysql-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1785,19 +1935,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra + run: tox -e py310-test-instrumentation-mysql-1 -- -ra - py39-test-instrumentation-mysqlclient: + py310-test-instrumentation-mysqlclient: name: instrumentation-mysqlclient runs-on: ubuntu-latest timeout-minutes: 30 @@ -1815,19 +1965,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra + run: tox -e py310-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-psycopg2: + py310-test-instrumentation-psycopg2: name: instrumentation-psycopg2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1845,19 +1995,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra + run: tox -e py310-test-instrumentation-psycopg2 -- -ra - py39-test-instrumentation-psycopg2-binary: + py310-test-instrumentation-psycopg2-binary: name: instrumentation-psycopg2-binary runs-on: ubuntu-latest timeout-minutes: 30 @@ -1875,19 +2025,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra + run: tox -e py310-test-instrumentation-psycopg2-binary -- -ra - py39-test-instrumentation-psycopg: + py310-test-instrumentation-psycopg: name: instrumentation-psycopg runs-on: ubuntu-latest timeout-minutes: 30 @@ -1905,19 +2055,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra + run: tox -e py310-test-instrumentation-psycopg -- -ra - py39-test-instrumentation-pymemcache-0: + py310-test-instrumentation-pymemcache-0: name: instrumentation-pymemcache-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1935,19 +2085,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - py39-test-instrumentation-pymemcache-1: + py310-test-instrumentation-pymemcache-1: name: instrumentation-pymemcache-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1965,19 +2115,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - py39-test-instrumentation-pymemcache-2: + py310-test-instrumentation-pymemcache-2: name: instrumentation-pymemcache-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -1995,19 +2145,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-2 -- -ra - py39-test-instrumentation-pymemcache-3: + py310-test-instrumentation-pymemcache-3: name: instrumentation-pymemcache-3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2025,19 +2175,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-3 -- -ra - py39-test-instrumentation-pymemcache-4: + py310-test-instrumentation-pymemcache-4: name: instrumentation-pymemcache-4 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2055,19 +2205,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-4 -- -ra - py39-test-instrumentation-pymongo: + py310-test-instrumentation-pymongo: name: instrumentation-pymongo runs-on: ubuntu-latest timeout-minutes: 30 @@ -2085,19 +2235,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymongo -- -ra + run: tox -e py310-test-instrumentation-pymongo -- -ra - py39-test-instrumentation-pymysql: + py310-test-instrumentation-pymysql: name: instrumentation-pymysql runs-on: ubuntu-latest timeout-minutes: 30 @@ -2115,19 +2265,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymysql -- -ra + run: tox -e py310-test-instrumentation-pymysql -- -ra - py39-test-instrumentation-pymssql: + py310-test-instrumentation-pymssql: name: instrumentation-pymssql runs-on: ubuntu-latest timeout-minutes: 30 @@ -2145,19 +2295,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymssql -- -ra + run: tox -e py310-test-instrumentation-pymssql -- -ra - py39-test-instrumentation-pyramid: + py310-test-instrumentation-pyramid: name: instrumentation-pyramid runs-on: ubuntu-latest timeout-minutes: 30 @@ -2175,19 +2325,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pyramid -- -ra + run: tox -e py310-test-instrumentation-pyramid -- -ra - py39-test-instrumentation-asgi: + py310-test-instrumentation-asgi: name: instrumentation-asgi runs-on: ubuntu-latest timeout-minutes: 30 @@ -2205,19 +2355,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asgi -- -ra + run: tox -e py310-test-instrumentation-asgi -- -ra - py39-test-instrumentation-asyncpg-wrapt1: + py310-test-instrumentation-asyncpg-wrapt1: name: instrumentation-asyncpg-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2235,19 +2385,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-asyncpg-wrapt1 -- -ra - py39-test-instrumentation-asyncpg-wrapt2: + py310-test-instrumentation-asyncpg-wrapt2: name: instrumentation-asyncpg-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2265,19 +2415,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-asyncpg-wrapt2 -- -ra - py39-test-instrumentation-sqlite3: + py310-test-instrumentation-sqlite3: name: instrumentation-sqlite3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2295,19 +2445,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlite3 -- -ra + run: tox -e py310-test-instrumentation-sqlite3 -- -ra - py39-test-instrumentation-wsgi: + py310-test-instrumentation-wsgi: name: instrumentation-wsgi runs-on: ubuntu-latest timeout-minutes: 30 @@ -2325,19 +2475,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra + run: tox -e py310-test-instrumentation-wsgi -- -ra - py39-test-instrumentation-grpc-0-wrapt1: + py310-test-instrumentation-grpc-0-wrapt1: name: instrumentation-grpc-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2355,19 +2505,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra - py39-test-instrumentation-grpc-0-wrapt2: + py310-test-instrumentation-grpc-0-wrapt2: name: instrumentation-grpc-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2385,19 +2535,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra - py39-test-instrumentation-grpc-1-wrapt1: + py310-test-instrumentation-grpc-1-wrapt1: name: instrumentation-grpc-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2415,19 +2565,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra - py39-test-instrumentation-grpc-1-wrapt2: + py310-test-instrumentation-grpc-1-wrapt2: name: instrumentation-grpc-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2445,19 +2595,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra - py39-test-instrumentation-sqlalchemy-1: + py310-test-instrumentation-sqlalchemy-1: name: instrumentation-sqlalchemy-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2475,19 +2625,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra + run: tox -e py310-test-instrumentation-sqlalchemy-1 -- -ra - py39-test-instrumentation-sqlalchemy-2: + py310-test-instrumentation-sqlalchemy-2: name: instrumentation-sqlalchemy-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2505,19 +2655,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra + run: tox -e py310-test-instrumentation-sqlalchemy-2 -- -ra - py39-test-instrumentation-redis: + py310-test-instrumentation-redis: name: instrumentation-redis runs-on: ubuntu-latest timeout-minutes: 30 @@ -2535,19 +2685,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-redis -- -ra + run: tox -e py310-test-instrumentation-redis -- -ra - py39-test-instrumentation-remoulade: + py310-test-instrumentation-remoulade: name: instrumentation-remoulade runs-on: ubuntu-latest timeout-minutes: 30 @@ -2565,19 +2715,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-remoulade -- -ra + run: tox -e py310-test-instrumentation-remoulade -- -ra - py39-test-instrumentation-celery: + py310-test-instrumentation-celery: name: instrumentation-celery runs-on: ubuntu-latest timeout-minutes: 30 @@ -2595,19 +2745,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-celery -- -ra + run: tox -e py310-test-instrumentation-celery -- -ra - py39-test-instrumentation-system-metrics: + py310-test-instrumentation-system-metrics: name: instrumentation-system-metrics runs-on: ubuntu-latest timeout-minutes: 30 @@ -2625,19 +2775,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-system-metrics -- -ra + run: tox -e py310-test-instrumentation-system-metrics -- -ra - py39-test-instrumentation-threading: + py310-test-instrumentation-threading: name: instrumentation-threading runs-on: ubuntu-latest timeout-minutes: 30 @@ -2655,19 +2805,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-threading -- -ra + run: tox -e py310-test-instrumentation-threading -- -ra - py39-test-instrumentation-tornado: + py310-test-instrumentation-tornado: name: instrumentation-tornado runs-on: ubuntu-latest timeout-minutes: 30 @@ -2685,19 +2835,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-tornado -- -ra + run: tox -e py310-test-instrumentation-tornado -- -ra - py39-test-instrumentation-tortoiseorm: + py310-test-instrumentation-tortoiseorm: name: instrumentation-tortoiseorm runs-on: ubuntu-latest timeout-minutes: 30 @@ -2715,19 +2865,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-tortoiseorm -- -ra + run: tox -e py310-test-instrumentation-tortoiseorm -- -ra - py39-test-instrumentation-httpx-0-wrapt1: + py310-test-instrumentation-httpx-0-wrapt1: name: instrumentation-httpx-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2745,19 +2895,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-httpx-0-wrapt1 -- -ra - py39-test-instrumentation-httpx-0-wrapt2: + py310-test-instrumentation-httpx-0-wrapt2: name: instrumentation-httpx-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2775,19 +2925,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-httpx-0-wrapt2 -- -ra - py39-test-instrumentation-httpx-1-wrapt1: + py310-test-instrumentation-httpx-1-wrapt1: name: instrumentation-httpx-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2805,19 +2955,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-httpx-1-wrapt1 -- -ra - py39-test-instrumentation-httpx-1-wrapt2: + py310-test-instrumentation-httpx-1-wrapt2: name: instrumentation-httpx-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2835,19 +2985,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-httpx-1-wrapt2 -- -ra - py39-test-util-http: + py310-test-util-http: name: util-http runs-on: ubuntu-latest timeout-minutes: 30 @@ -2865,19 +3015,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-util-http -- -ra + run: tox -e py310-test-util-http -- -ra - py39-test-exporter-credential-provider-gcp: + py310-test-exporter-credential-provider-gcp: name: exporter-credential-provider-gcp runs-on: ubuntu-latest timeout-minutes: 30 @@ -2895,19 +3045,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-exporter-credential-provider-gcp -- -ra + run: tox -e py310-test-exporter-credential-provider-gcp -- -ra - py39-test-util-genai: + py310-test-util-genai: name: util-genai runs-on: ubuntu-latest timeout-minutes: 30 @@ -2925,19 +3075,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-util-genai -- -ra + run: tox -e py310-test-util-genai -- -ra - py39-test-propagator-aws-xray-0: + py310-test-propagator-aws-xray-0: name: propagator-aws-xray-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2955,19 +3105,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-aws-xray-0 -- -ra + run: tox -e py310-test-propagator-aws-xray-0 -- -ra - py39-test-propagator-aws-xray-1: + py310-test-propagator-aws-xray-1: name: propagator-aws-xray-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -2985,19 +3135,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-aws-xray-1 -- -ra + run: tox -e py310-test-propagator-aws-xray-1 -- -ra - py39-test-propagator-ot-trace: + py310-test-propagator-ot-trace: name: propagator-ot-trace runs-on: ubuntu-latest timeout-minutes: 30 @@ -3015,19 +3165,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-propagator-ot-trace -- -ra + run: tox -e py310-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-0-wrapt1: + py310-test-instrumentation-sio-pika-0-wrapt1: name: instrumentation-sio-pika-0-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3045,19 +3195,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-0-wrapt1 -- -ra - py39-test-instrumentation-sio-pika-0-wrapt2: + py310-test-instrumentation-sio-pika-0-wrapt2: name: instrumentation-sio-pika-0-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3075,19 +3225,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-0-wrapt2 -- -ra - py39-test-instrumentation-sio-pika-1-wrapt1: + py310-test-instrumentation-sio-pika-1-wrapt1: name: instrumentation-sio-pika-1-wrapt1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3105,19 +3255,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-1-wrapt1 -- -ra - py39-test-instrumentation-sio-pika-1-wrapt2: + py310-test-instrumentation-sio-pika-1-wrapt2: name: instrumentation-sio-pika-1-wrapt2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3135,19 +3285,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-sio-pika-1-wrapt2 -- -ra - py39-test-instrumentation-aio-pika-0: + py310-test-instrumentation-aio-pika-0: name: instrumentation-aio-pika-0 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3165,19 +3315,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-0 -- -ra - py39-test-instrumentation-aio-pika-1: + py310-test-instrumentation-aio-pika-1: name: instrumentation-aio-pika-1 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3195,19 +3345,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-1 -- -ra - py39-test-instrumentation-aio-pika-2: + py310-test-instrumentation-aio-pika-2: name: instrumentation-aio-pika-2 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3225,19 +3375,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-2 -- -ra - py39-test-instrumentation-aio-pika-3: + py310-test-instrumentation-aio-pika-3: name: instrumentation-aio-pika-3 runs-on: ubuntu-latest timeout-minutes: 30 @@ -3255,19 +3405,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra + run: tox -e py310-test-instrumentation-aio-pika-3 -- -ra - py39-test-instrumentation-aiokafka: + py310-test-instrumentation-aiokafka: name: instrumentation-aiokafka runs-on: ubuntu-latest timeout-minutes: 30 @@ -3285,19 +3435,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-aiokafka -- -ra + run: tox -e py310-test-instrumentation-aiokafka -- -ra - py39-test-instrumentation-kafka-python: + py310-test-instrumentation-kafka-python: name: instrumentation-kafka-python runs-on: ubuntu-latest timeout-minutes: 30 @@ -3315,19 +3465,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-kafka-python -- -ra + run: tox -e py310-test-instrumentation-kafka-python -- -ra - py39-test-instrumentation-kafka-pythonng: + py310-test-instrumentation-kafka-pythonng: name: instrumentation-kafka-pythonng runs-on: ubuntu-latest timeout-minutes: 30 @@ -3345,19 +3495,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra + run: tox -e py310-test-instrumentation-kafka-pythonng -- -ra - py39-test-instrumentation-confluent-kafka: + py310-test-instrumentation-confluent-kafka: name: instrumentation-confluent-kafka runs-on: ubuntu-latest timeout-minutes: 30 @@ -3375,19 +3525,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-confluent-kafka -- -ra + run: tox -e py310-test-instrumentation-confluent-kafka -- -ra - py39-test-instrumentation-asyncio: + py310-test-instrumentation-asyncio: name: instrumentation-asyncio runs-on: ubuntu-latest timeout-minutes: 30 @@ -3405,19 +3555,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-asyncio -- -ra + run: tox -e py310-test-instrumentation-asyncio -- -ra - py39-test-instrumentation-cassandra-driver: + py310-test-instrumentation-cassandra-driver: name: instrumentation-cassandra-driver runs-on: ubuntu-latest timeout-minutes: 30 @@ -3435,19 +3585,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-driver -- -ra + run: tox -e py310-test-instrumentation-cassandra-driver -- -ra - py39-test-instrumentation-cassandra-scylla: + py310-test-instrumentation-cassandra-scylla: name: instrumentation-cassandra-scylla runs-on: ubuntu-latest timeout-minutes: 30 @@ -3465,19 +3615,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-scylla -- -ra + run: tox -e py310-test-instrumentation-cassandra-scylla -- -ra - py39-test-processor-baggage: + py310-test-processor-baggage: name: processor-baggage runs-on: ubuntu-latest timeout-minutes: 30 @@ -3495,19 +3645,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra + run: tox -e py310-test-processor-baggage -- -ra - py39-test-opamp-client-latest: + py310-test-opamp-client-latest: name: opamp-client-latest runs-on: ubuntu-latest timeout-minutes: 30 @@ -3525,19 +3675,19 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opamp-client-latest -- -ra + run: tox -e py310-test-opamp-client-latest -- -ra - py39-test-opamp-client-lowest: + py310-test-opamp-client-lowest: name: opamp-client-lowest runs-on: ubuntu-latest timeout-minutes: 30 @@ -3555,14 +3705,14 @@ jobs: ref: ${{ env.CORE_REPO_SHA }} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-opamp-client-lowest -- -ra + run: tox -e py310-test-opamp-client-lowest -- -ra diff --git a/.github/workflows/generate_workflows_lib/pyproject.toml b/.github/workflows/generate_workflows_lib/pyproject.toml index 04106efc0f8..16bba5576c7 100644 --- a/.github/workflows/generate_workflows_lib/pyproject.toml +++ b/.github/workflows/generate_workflows_lib/pyproject.toml @@ -7,7 +7,7 @@ name = "generate-workflows-lib" dynamic = ["version"] description = "A library to generate workflows" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -17,7 +17,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py index a2e628a09ec..10f4ad921f8 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py @@ -14,7 +14,7 @@ ) _tox_lint_env_regex = re_compile(r"lint-(?P[-\w]+)") _tox_contrib_env_regex = re_compile( - r"py39-test-(?P[-\w]+\w)-?(?P\d+)?" + r"py310-test-(?P[-\w]+\w)-?(?P\d+)?" ) @@ -47,9 +47,7 @@ def get_test_job_datas(tox_envs: list, operating_systems: list) -> list: os_alias = {"ubuntu-latest": "Ubuntu", "windows-latest": "Windows"} python_version_alias = { - "pypy3": "pypy-3.9", - "pypy310": "pypy-3.10", - "py39": "3.9", + "pypy3": "pypy-3.10", "py310": "3.10", "py311": "3.11", "py312": "3.12", diff --git a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 index 5fce8e1cfe2..46090ed333f 100644 --- a/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 +++ b/.github/workflows/generate_workflows_lib/src/generate_workflows_lib/core_contrib_test.yml.j2 @@ -46,10 +46,10 @@ jobs: ref: ${% raw %}{{ env.CORE_REPO_SHA }}{% endraw %} path: opentelemetry-python - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install tox diff --git a/.github/workflows/package-prepare-patch-release.yml b/.github/workflows/package-prepare-patch-release.yml index 917a579cfa4..5ad56159782 100644 --- a/.github/workflows/package-prepare-patch-release.yml +++ b/.github/workflows/package-prepare-patch-release.yml @@ -97,10 +97,10 @@ jobs: # replace the version in the version file (1.2.3 -> 1.2.4) sed -i -E "s/__version__\s*=\s*\"${VERSION}\"/__version__ = \"${NEXT_VERSION}\"/g" $VERSION_FILE - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox diff --git a/.github/workflows/package-prepare-release.yml b/.github/workflows/package-prepare-release.yml index 56b80728757..f9819d3668c 100644 --- a/.github/workflows/package-prepare-release.yml +++ b/.github/workflows/package-prepare-release.yml @@ -125,10 +125,10 @@ jobs: # replace the version in the version file (1.2.3dev -> 1.2.3) sed -i -E "s/__version__\s*=\s*\"${VERSION}\.dev\"/__version__ = \"${VERSION}\"/g" $VERSION_FILE - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox @@ -185,10 +185,10 @@ jobs: # replace the version in the version file (1.2.3dev -> 1.3.3.dev) sed -i -E "s/__version__\s*=\s*\"${VERSION}\.dev\"/__version__ = \"${NEXT_VERSION}.dev\"/g" $VERSION_FILE - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml index 7eb4b09d03d..3ab6341b551 100644 --- a/.github/workflows/package-release.yml +++ b/.github/workflows/package-release.yml @@ -88,7 +88,7 @@ jobs: # next few steps publish to pypi - uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.10' - name: Build wheels run: ./scripts/build_a_package.sh diff --git a/.github/workflows/prepare-patch-release.yml b/.github/workflows/prepare-patch-release.yml index 577fc86ba4f..b2ebdf41f1d 100644 --- a/.github/workflows/prepare-patch-release.yml +++ b/.github/workflows/prepare-patch-release.yml @@ -59,10 +59,10 @@ jobs: - name: Update version run: .github/scripts/update-version-patch.sh $STABLE_VERSION $UNSTABLE_VERSION $STABLE_VERSION_PREV $UNSTABLE_VERSION_PREV - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox diff --git a/.github/workflows/prepare-release-branch.yml b/.github/workflows/prepare-release-branch.yml index 1017a49a703..6804d112a6d 100644 --- a/.github/workflows/prepare-release-branch.yml +++ b/.github/workflows/prepare-release-branch.yml @@ -82,10 +82,10 @@ jobs: - name: Update version run: .github/scripts/update-version.sh $STABLE_VERSION $UNSTABLE_VERSION - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox @@ -184,10 +184,10 @@ jobs: - name: Update version run: .github/scripts/update-version.sh $STABLE_NEXT_VERSION $UNSTABLE_NEXT_VERSION - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install tox run: pip install tox - name: run tox diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e8fbb0dd36b..d7190f687f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -71,7 +71,7 @@ jobs: # next few steps publish to pypi - uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.10' - name: Build wheels run: ./scripts/build.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8aba00e1c21..9c694007ea7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,44 +24,6 @@ env: jobs: - py39-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-oldest -- -ra - - py39-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-openai-v2-latest -- -ra - py310-test-instrumentation-openai-v2-oldest_ubuntu-latest: name: instrumentation-openai-v2-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -272,17 +234,17 @@ jobs: run: tox -e py313-test-instrumentation-openai-v2-pydantic1 -- -ra pypy3-test-instrumentation-openai-v2-oldest_ubuntu-latest: - name: instrumentation-openai-v2-oldest pypy-3.9 Ubuntu + name: instrumentation-openai-v2-oldest pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -291,17 +253,17 @@ jobs: run: tox -e pypy3-test-instrumentation-openai-v2-oldest -- -ra pypy3-test-instrumentation-openai-v2-latest_ubuntu-latest: - name: instrumentation-openai-v2-latest pypy-3.9 Ubuntu + name: instrumentation-openai-v2-latest pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -499,44 +461,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-openai_agents-v2-latest -- -ra - py39-test-instrumentation-vertexai-oldest_ubuntu-latest: - name: instrumentation-vertexai-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-oldest -- -ra - - py39-test-instrumentation-vertexai-latest_ubuntu-latest: - name: instrumentation-vertexai-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-vertexai-latest -- -ra - py310-test-instrumentation-vertexai-oldest_ubuntu-latest: name: instrumentation-vertexai-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -727,44 +651,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-vertexai-latest -- -ra - py39-test-instrumentation-google-genai-oldest_ubuntu-latest: - name: instrumentation-google-genai-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-oldest -- -ra - - py39-test-instrumentation-google-genai-latest_ubuntu-latest: - name: instrumentation-google-genai-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-google-genai-latest -- -ra - py310-test-instrumentation-google-genai-oldest_ubuntu-latest: name: instrumentation-google-genai-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -955,44 +841,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-google-genai-latest -- -ra - py39-test-instrumentation-anthropic-oldest_ubuntu-latest: - name: instrumentation-anthropic-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-oldest -- -ra - - py39-test-instrumentation-anthropic-latest_ubuntu-latest: - name: instrumentation-anthropic-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-anthropic-latest -- -ra - py310-test-instrumentation-anthropic-oldest_ubuntu-latest: name: instrumentation-anthropic-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -1335,25 +1183,6 @@ jobs: - name: Run tests run: tox -e py313-test-instrumentation-claude-agent-sdk-latest -- -ra - py39-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-containerid -- -ra - py310-test-resource-detector-containerid_ubuntu-latest: name: resource-detector-containerid 3.10 Ubuntu runs-on: ubuntu-latest @@ -1450,17 +1279,17 @@ jobs: run: tox -e py314-test-resource-detector-containerid -- -ra pypy3-test-resource-detector-containerid_ubuntu-latest: - name: resource-detector-containerid pypy-3.9 Ubuntu + name: resource-detector-containerid pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -1468,44 +1297,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-resource-detector-containerid -- -ra - py39-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-azure-0 -- -ra - - py39-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-resource-detector-azure-1 -- -ra - py310-test-resource-detector-azure-0_ubuntu-latest: name: resource-detector-azure-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -1697,17 +1488,17 @@ jobs: run: tox -e py314-test-resource-detector-azure-1 -- -ra pypy3-test-resource-detector-azure-0_ubuntu-latest: - name: resource-detector-azure-0 pypy-3.9 Ubuntu + name: resource-detector-azure-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -1716,17 +1507,17 @@ jobs: run: tox -e pypy3-test-resource-detector-azure-0 -- -ra pypy3-test-resource-detector-azure-1_ubuntu-latest: - name: resource-detector-azure-1 pypy-3.9 Ubuntu + name: resource-detector-azure-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -1734,44 +1525,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-resource-detector-azure-1 -- -ra - py39-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-sdk-extension-aws-0 -- -ra - - py39-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-sdk-extension-aws-1 -- -ra - py310-test-sdk-extension-aws-0_ubuntu-latest: name: sdk-extension-aws-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -1963,17 +1716,17 @@ jobs: run: tox -e py314-test-sdk-extension-aws-1 -- -ra pypy3-test-sdk-extension-aws-0_ubuntu-latest: - name: sdk-extension-aws-0 pypy-3.9 Ubuntu + name: sdk-extension-aws-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -1982,17 +1735,17 @@ jobs: run: tox -e pypy3-test-sdk-extension-aws-0 -- -ra pypy3-test-sdk-extension-aws-1_ubuntu-latest: - name: sdk-extension-aws-1 pypy-3.9 Ubuntu + name: sdk-extension-aws-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2000,25 +1753,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-sdk-extension-aws-1 -- -ra - py39-test-distro_ubuntu-latest: - name: distro 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-distro -- -ra - py310-test-distro_ubuntu-latest: name: distro 3.10 Ubuntu runs-on: ubuntu-latest @@ -2115,17 +1849,17 @@ jobs: run: tox -e py314-test-distro -- -ra pypy3-test-distro_ubuntu-latest: - name: distro pypy-3.9 Ubuntu + name: distro pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2133,44 +1867,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-distro -- -ra - py39-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt1 -- -ra - - py39-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opentelemetry-instrumentation-wrapt2 -- -ra - py310-test-opentelemetry-instrumentation-wrapt1_ubuntu-latest: name: opentelemetry-instrumentation-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -2362,17 +2058,17 @@ jobs: run: tox -e py314-test-opentelemetry-instrumentation-wrapt2 -- -ra pypy3-test-opentelemetry-instrumentation-wrapt2_ubuntu-latest: - name: opentelemetry-instrumentation-wrapt2 pypy-3.9 Ubuntu + name: opentelemetry-instrumentation-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2380,25 +2076,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-opentelemetry-instrumentation-wrapt2 -- -ra - py39-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-client -- -ra - py310-test-instrumentation-aiohttp-client_ubuntu-latest: name: instrumentation-aiohttp-client 3.10 Ubuntu runs-on: ubuntu-latest @@ -2495,17 +2172,17 @@ jobs: run: tox -e py314-test-instrumentation-aiohttp-client -- -ra pypy3-test-instrumentation-aiohttp-client_ubuntu-latest: - name: instrumentation-aiohttp-client pypy-3.9 Ubuntu + name: instrumentation-aiohttp-client pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2513,25 +2190,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aiohttp-client -- -ra - py39-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiohttp-server -- -ra - py310-test-instrumentation-aiohttp-server_ubuntu-latest: name: instrumentation-aiohttp-server 3.10 Ubuntu runs-on: ubuntu-latest @@ -2628,17 +2286,17 @@ jobs: run: tox -e py314-test-instrumentation-aiohttp-server -- -ra pypy3-test-instrumentation-aiohttp-server_ubuntu-latest: - name: instrumentation-aiohttp-server pypy-3.9 Ubuntu + name: instrumentation-aiohttp-server pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -2646,44 +2304,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aiohttp-server -- -ra - py39-test-instrumentation-aiopg-wrapt1_ubuntu-latest: - name: instrumentation-aiopg-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt1 -- -ra - - py39-test-instrumentation-aiopg-wrapt2_ubuntu-latest: - name: instrumentation-aiopg-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiopg-wrapt2 -- -ra - py310-test-instrumentation-aiopg-wrapt1_ubuntu-latest: name: instrumentation-aiopg-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -2874,25 +2494,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-aiopg-wrapt2 -- -ra - py39-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aws-lambda -- -ra - py310-test-instrumentation-aws-lambda_ubuntu-latest: name: instrumentation-aws-lambda 3.10 Ubuntu runs-on: ubuntu-latest @@ -2989,17 +2590,17 @@ jobs: run: tox -e py314-test-instrumentation-aws-lambda -- -ra pypy3-test-instrumentation-aws-lambda_ubuntu-latest: - name: instrumentation-aws-lambda pypy-3.9 Ubuntu + name: instrumentation-aws-lambda pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -3007,82 +2608,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aws-lambda -- -ra - py39-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: - name: instrumentation-botocore-0-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt1 -- -ra - - py39-test-instrumentation-botocore-0-wrapt2_ubuntu-latest: - name: instrumentation-botocore-0-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-0-wrapt2 -- -ra - - py39-test-instrumentation-botocore-1-wrapt1_ubuntu-latest: - name: instrumentation-botocore-1-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt1 -- -ra - - py39-test-instrumentation-botocore-1-wrapt2_ubuntu-latest: - name: instrumentation-botocore-1-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-1-wrapt2 -- -ra - py310-test-instrumentation-botocore-0-wrapt1_ubuntu-latest: name: instrumentation-botocore-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -3463,44 +2988,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-botocore-1-wrapt2 -- -ra - py39-test-instrumentation-botocore-2_ubuntu-latest: - name: instrumentation-botocore-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-2 -- -ra - - py39-test-instrumentation-botocore-3_ubuntu-latest: - name: instrumentation-botocore-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-botocore-3 -- -ra - py310-test-instrumentation-botocore-2_ubuntu-latest: name: instrumentation-botocore-2 3.10 Ubuntu runs-on: ubuntu-latest @@ -3691,25 +3178,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-botocore-3 -- -ra - py39-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-boto3sqs -- -ra - py310-test-instrumentation-boto3sqs_ubuntu-latest: name: instrumentation-boto3sqs 3.10 Ubuntu runs-on: ubuntu-latest @@ -3806,17 +3274,17 @@ jobs: run: tox -e py314-test-instrumentation-boto3sqs -- -ra pypy3-test-instrumentation-boto3sqs_ubuntu-latest: - name: instrumentation-boto3sqs pypy-3.9 Ubuntu + name: instrumentation-boto3sqs pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -3824,65 +3292,65 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-boto3sqs -- -ra - py39-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 3.9 Ubuntu + py310-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-0 -- -ra + run: tox -e py310-test-instrumentation-django-0 -- -ra - py39-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.9 Ubuntu + py310-test-instrumentation-django-1_ubuntu-latest: + name: instrumentation-django-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-1 -- -ra + run: tox -e py310-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-django-2_ubuntu-latest: - name: instrumentation-django-2 3.9 Ubuntu + py310-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-django-2 -- -ra + run: tox -e py310-test-instrumentation-django-2 -- -ra - py310-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 3.10 Ubuntu + py310-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -3898,26 +3366,26 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-django-1 -- -ra + run: tox -e py310-test-instrumentation-django-3 -- -ra - py310-test-instrumentation-django-3_ubuntu-latest: - name: instrumentation-django-3 3.10 Ubuntu + py311-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-django-3 -- -ra + run: tox -e py311-test-instrumentation-django-0 -- -ra py311-test-instrumentation-django-1_ubuntu-latest: name: instrumentation-django-1 3.11 Ubuntu @@ -3938,6 +3406,25 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-django-1 -- -ra + py311-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.11 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py311-test-instrumentation-django-2 -- -ra + py311-test-instrumentation-django-3_ubuntu-latest: name: instrumentation-django-3 3.11 Ubuntu runs-on: ubuntu-latest @@ -3957,6 +3444,25 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-django-3 -- -ra + py312-test-instrumentation-django-0_ubuntu-latest: + name: instrumentation-django-0 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-django-0 -- -ra + py312-test-instrumentation-django-1_ubuntu-latest: name: instrumentation-django-1 3.12 Ubuntu runs-on: ubuntu-latest @@ -3976,6 +3482,25 @@ jobs: - name: Run tests run: tox -e py312-test-instrumentation-django-1 -- -ra + py312-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 3.12 Ubuntu + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install tox + run: pip install tox-uv + + - name: Run tests + run: tox -e py312-test-instrumentation-django-2 -- -ra + py312-test-instrumentation-django-3_ubuntu-latest: name: instrumentation-django-3 3.12 Ubuntu runs-on: ubuntu-latest @@ -4034,17 +3559,17 @@ jobs: run: tox -e py314-test-instrumentation-django-3 -- -ra pypy3-test-instrumentation-django-0_ubuntu-latest: - name: instrumentation-django-0 pypy-3.9 Ubuntu + name: instrumentation-django-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4053,17 +3578,17 @@ jobs: run: tox -e pypy3-test-instrumentation-django-0 -- -ra pypy3-test-instrumentation-django-1_ubuntu-latest: - name: instrumentation-django-1 pypy-3.9 Ubuntu + name: instrumentation-django-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4071,43 +3596,43 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-django-1 -- -ra - py39-test-instrumentation-dbapi-wrapt1_ubuntu-latest: - name: instrumentation-dbapi-wrapt1 3.9 Ubuntu + pypy3-test-instrumentation-django-2_ubuntu-latest: + name: instrumentation-django-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt1 -- -ra + run: tox -e pypy3-test-instrumentation-django-2 -- -ra - py39-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 3.9 Ubuntu + pypy3-test-instrumentation-django-3_ubuntu-latest: + name: instrumentation-django-3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-dbapi-wrapt2 -- -ra + run: tox -e pypy3-test-instrumentation-django-3 -- -ra py310-test-instrumentation-dbapi-wrapt1_ubuntu-latest: name: instrumentation-dbapi-wrapt1 3.10 Ubuntu @@ -4300,17 +3825,17 @@ jobs: run: tox -e py314-test-instrumentation-dbapi-wrapt2 -- -ra pypy3-test-instrumentation-dbapi-wrapt2_ubuntu-latest: - name: instrumentation-dbapi-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-dbapi-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4318,25 +3843,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-dbapi-wrapt2 -- -ra - py39-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncclick -- -ra - py310-test-instrumentation-asyncclick_ubuntu-latest: name: instrumentation-asyncclick 3.10 Ubuntu runs-on: ubuntu-latest @@ -4433,17 +3939,17 @@ jobs: run: tox -e py314-test-instrumentation-asyncclick -- -ra pypy3-test-instrumentation-asyncclick_ubuntu-latest: - name: instrumentation-asyncclick pypy-3.9 Ubuntu + name: instrumentation-asyncclick pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4451,25 +3957,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-asyncclick -- -ra - py39-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-click -- -ra - py310-test-instrumentation-click_ubuntu-latest: name: instrumentation-click 3.10 Ubuntu runs-on: ubuntu-latest @@ -4566,17 +4053,17 @@ jobs: run: tox -e py314-test-instrumentation-click -- -ra pypy3-test-instrumentation-click_ubuntu-latest: - name: instrumentation-click pypy-3.9 Ubuntu + name: instrumentation-click pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4584,63 +4071,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-click -- -ra - py39-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-0 -- -ra - - py39-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-1 -- -ra - - py39-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-elasticsearch-2 -- -ra - py310-test-instrumentation-elasticsearch-0_ubuntu-latest: name: instrumentation-elasticsearch-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -4927,17 +4357,17 @@ jobs: run: tox -e py314-test-instrumentation-elasticsearch-2 -- -ra pypy3-test-instrumentation-elasticsearch-0_ubuntu-latest: - name: instrumentation-elasticsearch-0 pypy-3.9 Ubuntu + name: instrumentation-elasticsearch-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4946,17 +4376,17 @@ jobs: run: tox -e pypy3-test-instrumentation-elasticsearch-0 -- -ra pypy3-test-instrumentation-elasticsearch-1_ubuntu-latest: - name: instrumentation-elasticsearch-1 pypy-3.9 Ubuntu + name: instrumentation-elasticsearch-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4965,17 +4395,17 @@ jobs: run: tox -e pypy3-test-instrumentation-elasticsearch-1 -- -ra pypy3-test-instrumentation-elasticsearch-2_ubuntu-latest: - name: instrumentation-elasticsearch-2 pypy-3.9 Ubuntu + name: instrumentation-elasticsearch-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -4983,82 +4413,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-elasticsearch-2 -- -ra - py39-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-0 -- -ra - - py39-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-1 -- -ra - - py39-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-2 -- -ra - - py39-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-falcon-3 -- -ra - py310-test-instrumentation-falcon-1_ubuntu-latest: name: instrumentation-falcon-1 3.10 Ubuntu runs-on: ubuntu-latest @@ -5325,37 +4679,18 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-falcon-4 -- -ra - pypy3-test-instrumentation-falcon-0_ubuntu-latest: - name: instrumentation-falcon-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-falcon-0 -- -ra - pypy3-test-instrumentation-falcon-1_ubuntu-latest: - name: instrumentation-falcon-1 pypy-3.9 Ubuntu + name: instrumentation-falcon-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5364,17 +4699,17 @@ jobs: run: tox -e pypy3-test-instrumentation-falcon-1 -- -ra pypy3-test-instrumentation-falcon-2_ubuntu-latest: - name: instrumentation-falcon-2 pypy-3.9 Ubuntu + name: instrumentation-falcon-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5383,17 +4718,17 @@ jobs: run: tox -e pypy3-test-instrumentation-falcon-2 -- -ra pypy3-test-instrumentation-falcon-3_ubuntu-latest: - name: instrumentation-falcon-3 pypy-3.9 Ubuntu + name: instrumentation-falcon-3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5402,17 +4737,17 @@ jobs: run: tox -e pypy3-test-instrumentation-falcon-3 -- -ra pypy3-test-instrumentation-falcon-4_ubuntu-latest: - name: instrumentation-falcon-4 pypy-3.9 Ubuntu + name: instrumentation-falcon-4 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5420,25 +4755,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-falcon-4 -- -ra - py39-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-fastapi -- -ra - py310-test-instrumentation-fastapi_ubuntu-latest: name: instrumentation-fastapi 3.10 Ubuntu runs-on: ubuntu-latest @@ -5535,17 +4851,17 @@ jobs: run: tox -e py314-test-instrumentation-fastapi -- -ra pypy3-test-instrumentation-fastapi_ubuntu-latest: - name: instrumentation-fastapi pypy-3.9 Ubuntu + name: instrumentation-fastapi pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -5553,82 +4869,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-fastapi -- -ra - py39-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-0 -- -ra - - py39-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-1 -- -ra - - py39-test-instrumentation-flask-2_ubuntu-latest: - name: instrumentation-flask-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-2 -- -ra - - py39-test-instrumentation-flask-3_ubuntu-latest: - name: instrumentation-flask-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-flask-3 -- -ra - py310-test-instrumentation-flask-0_ubuntu-latest: name: instrumentation-flask-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -6010,17 +5250,17 @@ jobs: run: tox -e py314-test-instrumentation-flask-3 -- -ra pypy3-test-instrumentation-flask-0_ubuntu-latest: - name: instrumentation-flask-0 pypy-3.9 Ubuntu + name: instrumentation-flask-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6029,17 +5269,17 @@ jobs: run: tox -e pypy3-test-instrumentation-flask-0 -- -ra pypy3-test-instrumentation-flask-1_ubuntu-latest: - name: instrumentation-flask-1 pypy-3.9 Ubuntu + name: instrumentation-flask-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6047,25 +5287,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-flask-1 -- -ra - py39-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-urllib -- -ra - py310-test-instrumentation-urllib_ubuntu-latest: name: instrumentation-urllib 3.10 Ubuntu runs-on: ubuntu-latest @@ -6162,17 +5383,17 @@ jobs: run: tox -e py314-test-instrumentation-urllib -- -ra pypy3-test-instrumentation-urllib_ubuntu-latest: - name: instrumentation-urllib pypy-3.9 Ubuntu + name: instrumentation-urllib pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6180,100 +5401,62 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-urllib -- -ra - py39-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.9 Ubuntu + py310-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-0 -- -ra + run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - py39-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.9 Ubuntu + py310-test-instrumentation-urllib3-1_ubuntu-latest: + name: instrumentation-urllib3-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-urllib3-1 -- -ra + run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - py310-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.10 Ubuntu + py311-test-instrumentation-urllib3-0_ubuntu-latest: + name: instrumentation-urllib3-0 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-0 -- -ra - - py310-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-urllib3-1 -- -ra - - py311-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-instrumentation-urllib3-0 -- -ra + run: tox -e py311-test-instrumentation-urllib3-0 -- -ra py311-test-instrumentation-urllib3-1_ubuntu-latest: name: instrumentation-urllib3-1 3.11 Ubuntu @@ -6371,17 +5554,17 @@ jobs: run: tox -e py313-test-instrumentation-urllib3-1 -- -ra pypy3-test-instrumentation-urllib3-0_ubuntu-latest: - name: instrumentation-urllib3-0 pypy-3.9 Ubuntu + name: instrumentation-urllib3-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6390,17 +5573,17 @@ jobs: run: tox -e pypy3-test-instrumentation-urllib3-0 -- -ra pypy3-test-instrumentation-urllib3-1_ubuntu-latest: - name: instrumentation-urllib3-1 pypy-3.9 Ubuntu + name: instrumentation-urllib3-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6408,25 +5591,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-urllib3-1 -- -ra - py39-test-instrumentation-requests_ubuntu-latest: - name: instrumentation-requests 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-requests -- -ra - py310-test-instrumentation-requests_ubuntu-latest: name: instrumentation-requests 3.10 Ubuntu runs-on: ubuntu-latest @@ -6522,44 +5686,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-requests -- -ra - py39-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-starlette-oldest -- -ra - - py39-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-starlette-latest -- -ra - py310-test-instrumentation-starlette-oldest_ubuntu-latest: name: instrumentation-starlette-oldest 3.10 Ubuntu runs-on: ubuntu-latest @@ -6751,17 +5877,17 @@ jobs: run: tox -e py314-test-instrumentation-starlette-latest -- -ra pypy3-test-instrumentation-starlette-oldest_ubuntu-latest: - name: instrumentation-starlette-oldest pypy-3.9 Ubuntu + name: instrumentation-starlette-oldest pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6770,17 +5896,17 @@ jobs: run: tox -e pypy3-test-instrumentation-starlette-oldest -- -ra pypy3-test-instrumentation-starlette-latest_ubuntu-latest: - name: instrumentation-starlette-latest pypy-3.9 Ubuntu + name: instrumentation-starlette-latest pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6788,25 +5914,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-starlette-latest -- -ra - py39-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-jinja2 -- -ra - py310-test-instrumentation-jinja2_ubuntu-latest: name: instrumentation-jinja2 3.10 Ubuntu runs-on: ubuntu-latest @@ -6903,17 +6010,17 @@ jobs: run: tox -e py314-test-instrumentation-jinja2 -- -ra pypy3-test-instrumentation-jinja2_ubuntu-latest: - name: instrumentation-jinja2 pypy-3.9 Ubuntu + name: instrumentation-jinja2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -6921,25 +6028,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-jinja2 -- -ra - py39-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-logging -- -ra - py310-test-instrumentation-logging_ubuntu-latest: name: instrumentation-logging 3.10 Ubuntu runs-on: ubuntu-latest @@ -7036,17 +6124,17 @@ jobs: run: tox -e py314-test-instrumentation-logging -- -ra pypy3-test-instrumentation-logging_ubuntu-latest: - name: instrumentation-logging pypy-3.9 Ubuntu + name: instrumentation-logging pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7054,25 +6142,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-logging -- -ra - py39-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-richconsole -- -ra - py310-test-exporter-richconsole_ubuntu-latest: name: exporter-richconsole 3.10 Ubuntu runs-on: ubuntu-latest @@ -7169,17 +6238,17 @@ jobs: run: tox -e py314-test-exporter-richconsole -- -ra pypy3-test-exporter-richconsole_ubuntu-latest: - name: exporter-richconsole pypy-3.9 Ubuntu + name: exporter-richconsole pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7187,25 +6256,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-exporter-richconsole -- -ra - py39-test-exporter-prometheus-remote-write_ubuntu-latest: - name: exporter-prometheus-remote-write 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-prometheus-remote-write -- -ra - py310-test-exporter-prometheus-remote-write_ubuntu-latest: name: exporter-prometheus-remote-write 3.10 Ubuntu runs-on: ubuntu-latest @@ -7301,7 +6351,7 @@ jobs: - name: Run tests run: tox -e py314-test-exporter-prometheus-remote-write -- -ra - pypy310-test-exporter-prometheus-remote-write_ubuntu-latest: + pypy3-test-exporter-prometheus-remote-write_ubuntu-latest: name: exporter-prometheus-remote-write pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 @@ -7318,45 +6368,7 @@ jobs: run: pip install tox-uv - name: Run tests - run: tox -e pypy310-test-exporter-prometheus-remote-write -- -ra - - py39-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysql-0 -- -ra - - py39-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysql-1 -- -ra + run: tox -e pypy3-test-exporter-prometheus-remote-write -- -ra py310-test-instrumentation-mysql-0_ubuntu-latest: name: instrumentation-mysql-0 3.10 Ubuntu @@ -7549,17 +6561,17 @@ jobs: run: tox -e py314-test-instrumentation-mysql-1 -- -ra pypy3-test-instrumentation-mysql-0_ubuntu-latest: - name: instrumentation-mysql-0 pypy-3.9 Ubuntu + name: instrumentation-mysql-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7568,17 +6580,17 @@ jobs: run: tox -e pypy3-test-instrumentation-mysql-0 -- -ra pypy3-test-instrumentation-mysql-1_ubuntu-latest: - name: instrumentation-mysql-1 pypy-3.9 Ubuntu + name: instrumentation-mysql-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7586,25 +6598,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-mysql-1 -- -ra - py39-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-mysqlclient -- -ra - py310-test-instrumentation-mysqlclient_ubuntu-latest: name: instrumentation-mysqlclient 3.10 Ubuntu runs-on: ubuntu-latest @@ -7701,17 +6694,17 @@ jobs: run: tox -e py314-test-instrumentation-mysqlclient -- -ra pypy3-test-instrumentation-mysqlclient_ubuntu-latest: - name: instrumentation-mysqlclient pypy-3.9 Ubuntu + name: instrumentation-mysqlclient pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -7719,25 +6712,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-mysqlclient -- -ra - py39-test-instrumentation-psycopg2_ubuntu-latest: - name: instrumentation-psycopg2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2 -- -ra - py310-test-instrumentation-psycopg2_ubuntu-latest: name: instrumentation-psycopg2 3.10 Ubuntu runs-on: ubuntu-latest @@ -7833,25 +6807,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-psycopg2 -- -ra - py39-test-instrumentation-psycopg2-binary_ubuntu-latest: - name: instrumentation-psycopg2-binary 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg2-binary -- -ra - py310-test-instrumentation-psycopg2-binary_ubuntu-latest: name: instrumentation-psycopg2-binary 3.10 Ubuntu runs-on: ubuntu-latest @@ -7947,25 +6902,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-psycopg2-binary -- -ra - py39-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-psycopg -- -ra - py310-test-instrumentation-psycopg_ubuntu-latest: name: instrumentation-psycopg 3.10 Ubuntu runs-on: ubuntu-latest @@ -8062,17 +6998,17 @@ jobs: run: tox -e py314-test-instrumentation-psycopg -- -ra pypy3-test-instrumentation-psycopg_ubuntu-latest: - name: instrumentation-psycopg pypy-3.9 Ubuntu + name: instrumentation-psycopg pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8080,151 +7016,56 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-psycopg -- -ra - py39-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.9 Ubuntu + py310-test-instrumentation-pymemcache-0_ubuntu-latest: + name: instrumentation-pymemcache-0 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-0 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - py39-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.9 Ubuntu + py310-test-instrumentation-pymemcache-1_ubuntu-latest: + name: instrumentation-pymemcache-1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-1 -- -ra + run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - py39-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.9 Ubuntu + py310-test-instrumentation-pymemcache-2_ubuntu-latest: + name: instrumentation-pymemcache-2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-2 -- -ra - - py39-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-3 -- -ra - - py39-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymemcache-4 -- -ra - - py310-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-0 -- -ra - - py310-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-pymemcache-1 -- -ra - - py310-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" + python-version: "3.10" - name: Install tox run: pip install tox-uv @@ -8651,17 +7492,17 @@ jobs: run: tox -e py314-test-instrumentation-pymemcache-4 -- -ra pypy3-test-instrumentation-pymemcache-0_ubuntu-latest: - name: instrumentation-pymemcache-0 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8670,17 +7511,17 @@ jobs: run: tox -e pypy3-test-instrumentation-pymemcache-0 -- -ra pypy3-test-instrumentation-pymemcache-1_ubuntu-latest: - name: instrumentation-pymemcache-1 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8689,17 +7530,17 @@ jobs: run: tox -e pypy3-test-instrumentation-pymemcache-1 -- -ra pypy3-test-instrumentation-pymemcache-2_ubuntu-latest: - name: instrumentation-pymemcache-2 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8708,17 +7549,17 @@ jobs: run: tox -e pypy3-test-instrumentation-pymemcache-2 -- -ra pypy3-test-instrumentation-pymemcache-3_ubuntu-latest: - name: instrumentation-pymemcache-3 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8727,17 +7568,17 @@ jobs: run: tox -e pypy3-test-instrumentation-pymemcache-3 -- -ra pypy3-test-instrumentation-pymemcache-4_ubuntu-latest: - name: instrumentation-pymemcache-4 pypy-3.9 Ubuntu + name: instrumentation-pymemcache-4 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8745,25 +7586,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-pymemcache-4 -- -ra - py39-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymongo -- -ra - py310-test-instrumentation-pymongo_ubuntu-latest: name: instrumentation-pymongo 3.10 Ubuntu runs-on: ubuntu-latest @@ -8860,17 +7682,17 @@ jobs: run: tox -e py314-test-instrumentation-pymongo -- -ra pypy3-test-instrumentation-pymongo_ubuntu-latest: - name: instrumentation-pymongo pypy-3.9 Ubuntu + name: instrumentation-pymongo pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -8878,25 +7700,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-pymongo -- -ra - py39-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymysql -- -ra - py310-test-instrumentation-pymysql_ubuntu-latest: name: instrumentation-pymysql 3.10 Ubuntu runs-on: ubuntu-latest @@ -8993,17 +7796,17 @@ jobs: run: tox -e py314-test-instrumentation-pymysql -- -ra pypy3-test-instrumentation-pymysql_ubuntu-latest: - name: instrumentation-pymysql pypy-3.9 Ubuntu + name: instrumentation-pymysql pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9011,25 +7814,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-pymysql -- -ra - py39-test-instrumentation-pymssql_ubuntu-latest: - name: instrumentation-pymssql 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pymssql -- -ra - py310-test-instrumentation-pymssql_ubuntu-latest: name: instrumentation-pymssql 3.10 Ubuntu runs-on: ubuntu-latest @@ -9125,25 +7909,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-pymssql -- -ra - py39-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-pyramid -- -ra - py310-test-instrumentation-pyramid_ubuntu-latest: name: instrumentation-pyramid 3.10 Ubuntu runs-on: ubuntu-latest @@ -9240,17 +8005,17 @@ jobs: run: tox -e py314-test-instrumentation-pyramid -- -ra pypy3-test-instrumentation-pyramid_ubuntu-latest: - name: instrumentation-pyramid pypy-3.9 Ubuntu + name: instrumentation-pyramid pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9258,25 +8023,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-pyramid -- -ra - py39-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asgi -- -ra - py310-test-instrumentation-asgi_ubuntu-latest: name: instrumentation-asgi 3.10 Ubuntu runs-on: ubuntu-latest @@ -9373,17 +8119,17 @@ jobs: run: tox -e py314-test-instrumentation-asgi -- -ra pypy3-test-instrumentation-asgi_ubuntu-latest: - name: instrumentation-asgi pypy-3.9 Ubuntu + name: instrumentation-asgi pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9391,44 +8137,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-asgi -- -ra - py39-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: - name: instrumentation-asyncpg-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt1 -- -ra - - py39-test-instrumentation-asyncpg-wrapt2_ubuntu-latest: - name: instrumentation-asyncpg-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncpg-wrapt2 -- -ra - py310-test-instrumentation-asyncpg-wrapt1_ubuntu-latest: name: instrumentation-asyncpg-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -9619,25 +8327,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-asyncpg-wrapt2 -- -ra - py39-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlite3 -- -ra - py310-test-instrumentation-sqlite3_ubuntu-latest: name: instrumentation-sqlite3 3.10 Ubuntu runs-on: ubuntu-latest @@ -9734,17 +8423,17 @@ jobs: run: tox -e py314-test-instrumentation-sqlite3 -- -ra pypy3-test-instrumentation-sqlite3_ubuntu-latest: - name: instrumentation-sqlite3 pypy-3.9 Ubuntu + name: instrumentation-sqlite3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9752,25 +8441,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-sqlite3 -- -ra - py39-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-wsgi -- -ra - py310-test-instrumentation-wsgi_ubuntu-latest: name: instrumentation-wsgi 3.10 Ubuntu runs-on: ubuntu-latest @@ -9867,17 +8537,17 @@ jobs: run: tox -e py314-test-instrumentation-wsgi -- -ra pypy3-test-instrumentation-wsgi_ubuntu-latest: - name: instrumentation-wsgi pypy-3.9 Ubuntu + name: instrumentation-wsgi pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -9885,160 +8555,84 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-wsgi -- -ra - py39-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.9 Ubuntu + py310-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra - py39-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: - name: instrumentation-grpc-0-wrapt2 3.9 Ubuntu + py310-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: + name: instrumentation-grpc-0-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-0-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra - py39-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.9 Ubuntu + py310-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: + name: instrumentation-grpc-1-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt1 -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra - py39-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.9 Ubuntu + py310-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: + name: instrumentation-grpc-1-wrapt2 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-grpc-1-wrapt2 -- -ra + run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra - py310-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-0-wrapt1 -- -ra - - py310-test-instrumentation-grpc-0-wrapt2_ubuntu-latest: - name: instrumentation-grpc-0-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-0-wrapt2 -- -ra - - py310-test-instrumentation-grpc-1-wrapt1_ubuntu-latest: - name: instrumentation-grpc-1-wrapt1 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-1-wrapt1 -- -ra - - py310-test-instrumentation-grpc-1-wrapt2_ubuntu-latest: - name: instrumentation-grpc-1-wrapt2 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-instrumentation-grpc-1-wrapt2 -- -ra - - py311-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: - name: instrumentation-grpc-0-wrapt1 3.11 Ubuntu + py311-test-instrumentation-grpc-0-wrapt1_ubuntu-latest: + name: instrumentation-grpc-0-wrapt1 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -10265,44 +8859,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-grpc-1-wrapt2 -- -ra - py39-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-1 -- -ra - - py39-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-sqlalchemy-2 -- -ra - py310-test-instrumentation-sqlalchemy-1_ubuntu-latest: name: instrumentation-sqlalchemy-1 3.10 Ubuntu runs-on: ubuntu-latest @@ -10474,37 +9030,18 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-sqlalchemy-2 -- -ra - pypy3-test-instrumentation-sqlalchemy-0_ubuntu-latest: - name: instrumentation-sqlalchemy-0 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-instrumentation-sqlalchemy-0 -- -ra - pypy3-test-instrumentation-sqlalchemy-1_ubuntu-latest: - name: instrumentation-sqlalchemy-1 pypy-3.9 Ubuntu + name: instrumentation-sqlalchemy-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -10513,17 +9050,17 @@ jobs: run: tox -e pypy3-test-instrumentation-sqlalchemy-1 -- -ra pypy3-test-instrumentation-sqlalchemy-2_ubuntu-latest: - name: instrumentation-sqlalchemy-2 pypy-3.9 Ubuntu + name: instrumentation-sqlalchemy-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -10531,25 +9068,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-sqlalchemy-2 -- -ra - py39-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-redis -- -ra - py310-test-instrumentation-redis_ubuntu-latest: name: instrumentation-redis 3.10 Ubuntu runs-on: ubuntu-latest @@ -10646,17 +9164,17 @@ jobs: run: tox -e py314-test-instrumentation-redis -- -ra pypy3-test-instrumentation-redis_ubuntu-latest: - name: instrumentation-redis pypy-3.9 Ubuntu + name: instrumentation-redis pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -10664,25 +9182,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-redis -- -ra - py39-test-instrumentation-remoulade_ubuntu-latest: - name: instrumentation-remoulade 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-remoulade -- -ra - py310-test-instrumentation-remoulade_ubuntu-latest: name: instrumentation-remoulade 3.10 Ubuntu runs-on: ubuntu-latest @@ -10778,25 +9277,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-remoulade -- -ra - py39-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-celery -- -ra - py310-test-instrumentation-celery_ubuntu-latest: name: instrumentation-celery 3.10 Ubuntu runs-on: ubuntu-latest @@ -10893,17 +9373,17 @@ jobs: run: tox -e py314-test-instrumentation-celery -- -ra pypy3-test-instrumentation-celery_ubuntu-latest: - name: instrumentation-celery pypy-3.9 Ubuntu + name: instrumentation-celery pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -10911,25 +9391,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-celery -- -ra - py39-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-system-metrics -- -ra - py310-test-instrumentation-system-metrics_ubuntu-latest: name: instrumentation-system-metrics 3.10 Ubuntu runs-on: ubuntu-latest @@ -11026,17 +9487,17 @@ jobs: run: tox -e py314-test-instrumentation-system-metrics -- -ra pypy3-test-instrumentation-system-metrics_ubuntu-latest: - name: instrumentation-system-metrics pypy-3.9 Ubuntu + name: instrumentation-system-metrics pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11044,25 +9505,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-system-metrics -- -ra - py39-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-threading -- -ra - py310-test-instrumentation-threading_ubuntu-latest: name: instrumentation-threading 3.10 Ubuntu runs-on: ubuntu-latest @@ -11159,17 +9601,17 @@ jobs: run: tox -e py314-test-instrumentation-threading -- -ra pypy3-test-instrumentation-threading_ubuntu-latest: - name: instrumentation-threading pypy-3.9 Ubuntu + name: instrumentation-threading pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11177,25 +9619,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-threading -- -ra - py39-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-tornado -- -ra - py310-test-instrumentation-tornado_ubuntu-latest: name: instrumentation-tornado 3.10 Ubuntu runs-on: ubuntu-latest @@ -11292,17 +9715,17 @@ jobs: run: tox -e py314-test-instrumentation-tornado -- -ra pypy3-test-instrumentation-tornado_ubuntu-latest: - name: instrumentation-tornado pypy-3.9 Ubuntu + name: instrumentation-tornado pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11310,25 +9733,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-tornado -- -ra - py39-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-tortoiseorm -- -ra - py310-test-instrumentation-tortoiseorm_ubuntu-latest: name: instrumentation-tortoiseorm 3.10 Ubuntu runs-on: ubuntu-latest @@ -11425,17 +9829,17 @@ jobs: run: tox -e py314-test-instrumentation-tortoiseorm -- -ra pypy3-test-instrumentation-tortoiseorm_ubuntu-latest: - name: instrumentation-tortoiseorm pypy-3.9 Ubuntu + name: instrumentation-tortoiseorm pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11443,82 +9847,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-tortoiseorm -- -ra - py39-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: - name: instrumentation-httpx-0-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt1 -- -ra - - py39-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-0-wrapt2 -- -ra - - py39-test-instrumentation-httpx-1-wrapt1_ubuntu-latest: - name: instrumentation-httpx-1-wrapt1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt1 -- -ra - - py39-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-httpx-1-wrapt2 -- -ra - py310-test-instrumentation-httpx-0-wrapt1_ubuntu-latest: name: instrumentation-httpx-0-wrapt1 3.10 Ubuntu runs-on: ubuntu-latest @@ -11824,17 +10152,17 @@ jobs: run: tox -e py314-test-instrumentation-httpx-1-wrapt2 -- -ra pypy3-test-instrumentation-httpx-0-wrapt2_ubuntu-latest: - name: instrumentation-httpx-0-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-httpx-0-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11843,17 +10171,17 @@ jobs: run: tox -e pypy3-test-instrumentation-httpx-0-wrapt2 -- -ra pypy3-test-instrumentation-httpx-1-wrapt2_ubuntu-latest: - name: instrumentation-httpx-1-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-httpx-1-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11861,25 +10189,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-httpx-1-wrapt2 -- -ra - py39-test-util-http_ubuntu-latest: - name: util-http 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-util-http -- -ra - py310-test-util-http_ubuntu-latest: name: util-http 3.10 Ubuntu runs-on: ubuntu-latest @@ -11976,17 +10285,17 @@ jobs: run: tox -e py314-test-util-http -- -ra pypy3-test-util-http_ubuntu-latest: - name: util-http pypy-3.9 Ubuntu + name: util-http pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -11994,25 +10303,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-util-http -- -ra - py39-test-exporter-credential-provider-gcp_ubuntu-latest: - name: exporter-credential-provider-gcp 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-exporter-credential-provider-gcp -- -ra - py310-test-exporter-credential-provider-gcp_ubuntu-latest: name: exporter-credential-provider-gcp 3.10 Ubuntu runs-on: ubuntu-latest @@ -12108,25 +10398,6 @@ jobs: - name: Run tests run: tox -e py314-test-exporter-credential-provider-gcp -- -ra - py39-test-util-genai_ubuntu-latest: - name: util-genai 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-util-genai -- -ra - py310-test-util-genai_ubuntu-latest: name: util-genai 3.10 Ubuntu runs-on: ubuntu-latest @@ -12223,17 +10494,17 @@ jobs: run: tox -e py314-test-util-genai -- -ra pypy3-test-util-genai_ubuntu-latest: - name: util-genai pypy-3.9 Ubuntu + name: util-genai pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -12241,44 +10512,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-util-genai -- -ra - py39-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-aws-xray-0 -- -ra - - py39-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-aws-xray-1 -- -ra - py310-test-propagator-aws-xray-0_ubuntu-latest: name: propagator-aws-xray-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -12470,17 +10703,17 @@ jobs: run: tox -e py314-test-propagator-aws-xray-1 -- -ra pypy3-test-propagator-aws-xray-0_ubuntu-latest: - name: propagator-aws-xray-0 pypy-3.9 Ubuntu + name: propagator-aws-xray-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -12489,232 +10722,137 @@ jobs: run: tox -e pypy3-test-propagator-aws-xray-0 -- -ra pypy3-test-propagator-aws-xray-1_ubuntu-latest: - name: propagator-aws-xray-1 pypy-3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python pypy-3.9 - uses: actions/setup-python@v5 - with: - python-version: "pypy-3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra - - py39-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.9 Ubuntu + name: propagator-aws-xray-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-propagator-ot-trace -- -ra - - py310-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.10 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py310-test-propagator-ot-trace -- -ra - - py311-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.11 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py311-test-propagator-ot-trace -- -ra - - py312-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.12 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py312-test-propagator-ot-trace -- -ra - - py313-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.13 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.13 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py313-test-propagator-ot-trace -- -ra + run: tox -e pypy3-test-propagator-aws-xray-1 -- -ra - py314-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace 3.14 Ubuntu + py310-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.14 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: "3.14" + python-version: "3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py314-test-propagator-ot-trace -- -ra + run: tox -e py310-test-propagator-ot-trace -- -ra - pypy3-test-propagator-ot-trace_ubuntu-latest: - name: propagator-ot-trace pypy-3.9 Ubuntu + py311-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.11 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "3.11" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e pypy3-test-propagator-ot-trace -- -ra + run: tox -e py311-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt1 3.9 Ubuntu + py312-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.12 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt1 -- -ra + run: tox -e py312-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 3.9 Ubuntu + py313-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.13 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.13" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-0-wrapt2 -- -ra + run: tox -e py313-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-1-wrapt1_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt1 3.9 Ubuntu + py314-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace 3.14 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.14" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt1 -- -ra + run: tox -e py314-test-propagator-ot-trace -- -ra - py39-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 3.9 Ubuntu + pypy3-test-propagator-ot-trace_ubuntu-latest: + name: propagator-ot-trace pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv - name: Run tests - run: tox -e py39-test-instrumentation-sio-pika-1-wrapt2 -- -ra + run: tox -e pypy3-test-propagator-ot-trace -- -ra py310-test-instrumentation-sio-pika-0-wrapt1_ubuntu-latest: name: instrumentation-sio-pika-0-wrapt1 3.10 Ubuntu @@ -13097,17 +11235,17 @@ jobs: run: tox -e py314-test-instrumentation-sio-pika-1-wrapt2 -- -ra pypy3-test-instrumentation-sio-pika-0-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-0-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-sio-pika-0-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13116,17 +11254,17 @@ jobs: run: tox -e pypy3-test-instrumentation-sio-pika-0-wrapt2 -- -ra pypy3-test-instrumentation-sio-pika-1-wrapt2_ubuntu-latest: - name: instrumentation-sio-pika-1-wrapt2 pypy-3.9 Ubuntu + name: instrumentation-sio-pika-1-wrapt2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13134,82 +11272,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-sio-pika-1-wrapt2 -- -ra - py39-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-0 -- -ra - - py39-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-1 -- -ra - - py39-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-2 -- -ra - - py39-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aio-pika-3 -- -ra - py310-test-instrumentation-aio-pika-0_ubuntu-latest: name: instrumentation-aio-pika-0 3.10 Ubuntu runs-on: ubuntu-latest @@ -13591,17 +11653,17 @@ jobs: run: tox -e py314-test-instrumentation-aio-pika-3 -- -ra pypy3-test-instrumentation-aio-pika-0_ubuntu-latest: - name: instrumentation-aio-pika-0 pypy-3.9 Ubuntu + name: instrumentation-aio-pika-0 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13610,17 +11672,17 @@ jobs: run: tox -e pypy3-test-instrumentation-aio-pika-0 -- -ra pypy3-test-instrumentation-aio-pika-1_ubuntu-latest: - name: instrumentation-aio-pika-1 pypy-3.9 Ubuntu + name: instrumentation-aio-pika-1 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13629,17 +11691,17 @@ jobs: run: tox -e pypy3-test-instrumentation-aio-pika-1 -- -ra pypy3-test-instrumentation-aio-pika-2_ubuntu-latest: - name: instrumentation-aio-pika-2 pypy-3.9 Ubuntu + name: instrumentation-aio-pika-2 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13648,17 +11710,17 @@ jobs: run: tox -e pypy3-test-instrumentation-aio-pika-2 -- -ra pypy3-test-instrumentation-aio-pika-3_ubuntu-latest: - name: instrumentation-aio-pika-3 pypy-3.9 Ubuntu + name: instrumentation-aio-pika-3 pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13666,25 +11728,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aio-pika-3 -- -ra - py39-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-aiokafka -- -ra - py310-test-instrumentation-aiokafka_ubuntu-latest: name: instrumentation-aiokafka 3.10 Ubuntu runs-on: ubuntu-latest @@ -13781,17 +11824,17 @@ jobs: run: tox -e py314-test-instrumentation-aiokafka -- -ra pypy3-test-instrumentation-aiokafka_ubuntu-latest: - name: instrumentation-aiokafka pypy-3.9 Ubuntu + name: instrumentation-aiokafka pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13799,25 +11842,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-aiokafka -- -ra - py39-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-kafka-python -- -ra - py310-test-instrumentation-kafka-python_ubuntu-latest: name: instrumentation-kafka-python 3.10 Ubuntu runs-on: ubuntu-latest @@ -13856,25 +11880,6 @@ jobs: - name: Run tests run: tox -e py311-test-instrumentation-kafka-python -- -ra - py39-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-kafka-pythonng -- -ra - py310-test-instrumentation-kafka-pythonng_ubuntu-latest: name: instrumentation-kafka-pythonng 3.10 Ubuntu runs-on: ubuntu-latest @@ -13971,17 +11976,17 @@ jobs: run: tox -e py314-test-instrumentation-kafka-pythonng -- -ra pypy3-test-instrumentation-kafka-python_ubuntu-latest: - name: instrumentation-kafka-python pypy-3.9 Ubuntu + name: instrumentation-kafka-python pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -13990,17 +11995,17 @@ jobs: run: tox -e pypy3-test-instrumentation-kafka-python -- -ra pypy3-test-instrumentation-kafka-pythonng_ubuntu-latest: - name: instrumentation-kafka-pythonng pypy-3.9 Ubuntu + name: instrumentation-kafka-pythonng pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -14008,25 +12013,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-kafka-pythonng -- -ra - py39-test-instrumentation-confluent-kafka_ubuntu-latest: - name: instrumentation-confluent-kafka 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-confluent-kafka -- -ra - py310-test-instrumentation-confluent-kafka_ubuntu-latest: name: instrumentation-confluent-kafka 3.10 Ubuntu runs-on: ubuntu-latest @@ -14122,25 +12108,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-confluent-kafka -- -ra - py39-test-instrumentation-asyncio_ubuntu-latest: - name: instrumentation-asyncio 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-asyncio -- -ra - py310-test-instrumentation-asyncio_ubuntu-latest: name: instrumentation-asyncio 3.10 Ubuntu runs-on: ubuntu-latest @@ -14236,44 +12203,6 @@ jobs: - name: Run tests run: tox -e py314-test-instrumentation-asyncio -- -ra - py39-test-instrumentation-cassandra-driver_ubuntu-latest: - name: instrumentation-cassandra-driver 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-driver -- -ra - - py39-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-instrumentation-cassandra-scylla -- -ra - py310-test-instrumentation-cassandra-driver_ubuntu-latest: name: instrumentation-cassandra-driver 3.10 Ubuntu runs-on: ubuntu-latest @@ -14465,17 +12394,17 @@ jobs: run: tox -e py314-test-instrumentation-cassandra-scylla -- -ra pypy3-test-instrumentation-cassandra-scylla_ubuntu-latest: - name: instrumentation-cassandra-scylla pypy-3.9 Ubuntu + name: instrumentation-cassandra-scylla pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -14483,25 +12412,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-instrumentation-cassandra-scylla -- -ra - py39-test-processor-baggage_ubuntu-latest: - name: processor-baggage 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-processor-baggage -- -ra - py310-test-processor-baggage_ubuntu-latest: name: processor-baggage 3.10 Ubuntu runs-on: ubuntu-latest @@ -14598,17 +12508,17 @@ jobs: run: tox -e py314-test-processor-baggage -- -ra pypy3-test-processor-baggage_ubuntu-latest: - name: processor-baggage pypy-3.9 Ubuntu + name: processor-baggage pypy-3.10 Ubuntu runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout repo @ SHA - ${{ github.sha }} uses: actions/checkout@v4 - - name: Set up Python pypy-3.9 + - name: Set up Python pypy-3.10 uses: actions/setup-python@v5 with: - python-version: "pypy-3.9" + python-version: "pypy-3.10" - name: Install tox run: pip install tox-uv @@ -14616,44 +12526,6 @@ jobs: - name: Run tests run: tox -e pypy3-test-processor-baggage -- -ra - py39-test-opamp-client-latest_ubuntu-latest: - name: opamp-client-latest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opamp-client-latest -- -ra - - py39-test-opamp-client-lowest_ubuntu-latest: - name: opamp-client-lowest 3.9 Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - name: Set up Python 3.9 - uses: actions/setup-python@v5 - with: - python-version: "3.9" - - - name: Install tox - run: pip install tox-uv - - - name: Run tests - run: tox -e py39-test-opamp-client-lowest -- -ra - py310-test-opamp-client-latest_ubuntu-latest: name: opamp-client-latest 3.10 Ubuntu runs-on: ubuntu-latest diff --git a/.pylintrc b/.pylintrc index 33fcdc1983b..17f53f20985 100644 --- a/.pylintrc +++ b/.pylintrc @@ -46,7 +46,7 @@ suggestion-mode=yes unsafe-load-any-extension=no # Run python dependant checks considering the baseline version -py-version=3.9 +py-version=3.10 [MESSAGES CONTROL] @@ -76,11 +76,11 @@ disable=missing-docstring, exec-used, super-with-arguments, # temp-pylint-upgrade isinstance-second-argument-not-valid-type, # temp-pylint-upgrade - raise-missing-from, # temp-pylint-upgrade - unused-argument, # temp-pylint-upgrade - protected-access, # temp-pylint-upgrade + raise-missing-from, # temp-pylint-upgrade + unused-argument, # temp-pylint-upgrade + protected-access, # temp-pylint-upgrade super-init-not-called, # temp-pylint-upgrade - invalid-overridden-method, # temp-pylint-upgrade + invalid-overridden-method, # temp-pylint-upgrade missing-module-docstring, # temp-pylint-upgrade import-error, # needed as a workaround as reported here: https://github.com/open-telemetry/opentelemetry-python-contrib/issues/290 cyclic-import, diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c108e893e2..6dca6b771e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Breaking changes + +- Drop Python 3.9 support + ([#4412](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4412)) + ## Version 1.41.0/0.62b0 (2026-04-09) - + ### Added - `opentelemetry-instrumentation-asgi`: Respect `suppress_http_instrumentation` context in ASGI middleware to skip server span creation when HTTP instrumentation is suppressed @@ -45,7 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-grpc`: Fix bidirectional streaming RPCs raising `AttributeError: 'generator' object has no attribute 'add_done_callback'` ([#4259](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4259)) - `opentelemetry-instrumentation-aiokafka`: fix `Unclosed AIOKafkaProducer` warning and `RuntimeWarning: coroutine was never awaited` in tests - ([#4384](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4384)) + ([#4384](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4384)) - `opentelemetry-instrumentation-aiokafka`: Fix compatibility with aiokafka 0.13 by calling `_key_serializer`/`_value_serializer` directly instead of the internal `_serialize` method whose signature changed in 0.13 from `(topic, key, value)` to `(key, value, headers)` diff --git a/_template/pyproject.toml b/_template/pyproject.toml index c9f3ba3ed13..c579035d5ff 100644 --- a/_template/pyproject.toml +++ b/_template/pyproject.toml @@ -12,7 +12,7 @@ dynamic = ["version"] description = "" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -22,7 +22,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/dev-requirements.txt b/dev-requirements.txt index b2de8cecfce..29325a6d352 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -13,6 +13,5 @@ codespell==2.1.0 requests==2.32.3 ruamel.yaml==0.17.21 flaky==3.7.0 -pre-commit==3.7.0; python_version >= '3.9' -pre-commit==3.5.0; python_version < '3.9' +pre-commit==3.7.0 ruff==0.14.1 diff --git a/exporter/opentelemetry-exporter-credential-provider-gcp/pyproject.toml b/exporter/opentelemetry-exporter-credential-provider-gcp/pyproject.toml index 5eb6b7096be..d53c8e4a0a3 100644 --- a/exporter/opentelemetry-exporter-credential-provider-gcp/pyproject.toml +++ b/exporter/opentelemetry-exporter-credential-provider-gcp/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "GCP OTLP Exporter Credential Provider for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile b/exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile index 8b2d34d4214..4bde0b14bb0 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9 +FROM python:3.10 RUN apt-get update -y && apt-get install libsnappy-dev -y diff --git a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml index 40db4fc2551..285d0b22c64 100644 --- a/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml +++ b/exporter/opentelemetry-exporter-prometheus-remote-write/pyproject.toml @@ -9,7 +9,7 @@ dynamic = ["version"] description = "Prometheus Remote Write Metrics Exporter for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -19,7 +19,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/exporter/opentelemetry-exporter-richconsole/pyproject.toml b/exporter/opentelemetry-exporter-richconsole/pyproject.toml index 64f3589520d..805e28340a6 100644 --- a/exporter/opentelemetry-exporter-richconsole/pyproject.toml +++ b/exporter/opentelemetry-exporter-richconsole/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Rich Console Exporter for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml index 5cc6754ef79..6b0d72c3343 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Anthropic instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py index b2055a525f4..067ef0085e8 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/tests/test_async_wrappers.py @@ -405,13 +405,13 @@ async def test_async_stream_wrapper_processes_events_and_stops_on_completion(): wrapper._process_chunk = processed.append wrapper._stop = lambda: stopped.append(True) - result = await wrapper.__anext__() + result = await anext(wrapper) assert result is event assert processed == [event] with pytest.raises(StopAsyncIteration): - await wrapper.__anext__() + await anext(wrapper) assert stopped == [True] @@ -428,7 +428,7 @@ async def test_async_stream_wrapper_fails_and_reraises_stream_errors(): ) with pytest.raises(ValueError, match="boom"): - await wrapper.__anext__() + await anext(wrapper) assert failures == [("boom", ValueError)] diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml index 87b30343e33..2ea01de4f39 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml @@ -22,7 +22,7 @@ dynamic = ["version"] description = "OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -70,4 +70,4 @@ exclude = ["**/__pycache__"] stubPath = "types" reportMissingImports = "error" reportMissingTypeStubs = false -pythonVersion = "3.9" +pythonVersion = "3.10" diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/test_e2e.py b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/test_e2e.py index 47abf4b877f..c29fe28bd14 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/test_e2e.py +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/test_e2e.py @@ -24,11 +24,9 @@ output is the purview of the other tests in this directory.""" import asyncio -import gzip import json import os import subprocess -import sys import time import fsspec @@ -258,51 +256,6 @@ def _convert_body_to_literal(data): return data -# Helper for enforcing GZIP compression where it was originally. -def _ensure_gzip_single_response(data: bytes): - try: - # Attempt to decompress, first, to avoid double compression. - gzip.decompress(data) - return data - except gzip.BadGzipFile: - # It must not have been compressed in the first place. - return gzip.compress(data) - - -# VCRPy automatically decompresses responses before saving them, but it may forget to -# re-encode them when the data is loaded. This can create issues with decompression. -# This is why we re-encode on load; to accurately replay what was originally sent. -# -# https://vcrpy.readthedocs.io/en/latest/advanced.html#decode-compressed-response -def _ensure_casette_gzip(loaded_casette): - for interaction in loaded_casette["interactions"]: - response = interaction["response"] - headers = response["headers"] - if ( - "content-encoding" not in headers - and "Content-Encoding" not in headers - ): - continue - if ( - "content-encoding" in headers - and "gzip" not in headers["content-encoding"] - ): - continue - if ( - "Content-Encoding" in headers - and "gzip" not in headers["Content-Encoding"] - ): - continue - response["body"]["string"] = _ensure_gzip_single_response( - response["body"]["string"].encode() - ) - - -def _maybe_ensure_casette_gzip(result): - if sys.version_info[0] == 3 and sys.version_info[1] == 9: - _ensure_casette_gzip(result) - - class _PrettyPrintJSONBody: """This makes request and response body recordings more readable.""" @@ -315,9 +268,7 @@ def serialize(cassette_dict): @staticmethod def deserialize(cassette_string): - result = yaml.load(cassette_string, Loader=yaml.Loader) - _maybe_ensure_casette_gzip(result) - return result + return yaml.load(cassette_string, Loader=yaml.Loader) @pytest.fixture(name="fully_initialized_vcr", scope="module", autouse=True) diff --git a/instrumentation-genai/opentelemetry-instrumentation-langchain/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-langchain/pyproject.toml index 13947d25550..80a406b7dae 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-langchain/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-langchain/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official Langchain instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml index 61a63e60bf7..e87c28d879a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official OpenAI Agents instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index 7b4fcce2241..807d5bf9981 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official OpenAI instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py index 2789284b887..3061a23f3a7 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_wrappers.py @@ -371,13 +371,13 @@ async def test_async_stream_wrapper_processes_events_and_stops_on_completion(): wrapper.process_event = processed.append wrapper._stop = stopped.append - result = await wrapper.__anext__() + result = await anext(wrapper) assert result is event assert processed == [event] with pytest.raises(StopAsyncIteration): - await wrapper.__anext__() + await anext(wrapper) assert stopped == [None] @@ -416,7 +416,7 @@ def record_failure(message, error_type): wrapper._fail = record_failure with pytest.raises(ValueError, match="boom"): - await wrapper.__anext__() + await anext(wrapper) assert failures == [("boom", ValueError)] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml index e6090642f6d..91a58956989 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official VertexAI instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation-genai/opentelemetry-instrumentation-weaviate/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-weaviate/pyproject.toml index 2489c378957..7ff31901dee 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-weaviate/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-weaviate/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Official Weaviate Client Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml index 7eb7f04f2ce..2f57713d0de 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Aio-pika instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml index ef895020ab6..f908184beb3 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry aiohttp client instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml index 779db188c4b..6c1d86d8fab 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-server/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Aiohttp server instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io"} ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml index 9c9827a3c0e..52714ef384a 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry aiokafka instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py index 646232da356..e0812fe1c52 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/tests/test_instrumentation.py @@ -14,10 +14,9 @@ from __future__ import annotations -import sys import uuid from typing import Any, Sequence, cast -from unittest import IsolatedAsyncioTestCase, TestCase, mock, skipIf +from unittest import IsolatedAsyncioTestCase, TestCase, mock import aiokafka from aiokafka import ( @@ -64,10 +63,6 @@ def test_instrument_api(self) -> None: ) -@skipIf( - sys.version_info < (3, 10), - "aiokafka >= 0.13 requires Python 3.10+", -) class TestAIOKafkaInstrumentation(TestBase, IsolatedAsyncioTestCase): @staticmethod def consumer_record_factory( @@ -266,21 +261,12 @@ async def async_consume_hook(span, *_) -> None: async def test_getone_consume_hook(self) -> None: async_consume_hook_mock = mock.AsyncMock() - def is_async_consume_hook_mock(obj: Any) -> bool: - return obj is async_consume_hook_mock - AIOKafkaInstrumentor().uninstrument() - # TODO: remove mock.patch when we drop Python 3.9 support - with mock.patch( - "opentelemetry.instrumentation.aiokafka.iscoroutinefunction" - ) as iscoro: - iscoro.side_effect = is_async_consume_hook_mock - - AIOKafkaInstrumentor().instrument( - tracer_provider=self.tracer_provider, - async_consume_hook=async_consume_hook_mock, - ) + AIOKafkaInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_consume_hook=async_consume_hook_mock, + ) consumer = await self.consumer_factory() self.addAsyncCleanup(consumer.stop) @@ -463,20 +449,11 @@ async def test_send_baggage(self) -> None: async def test_send_produce_hook(self) -> None: async_produce_hook_mock = mock.AsyncMock() - def is_async_produce_hook_mock(obj: Any) -> bool: - return obj is async_produce_hook_mock - AIOKafkaInstrumentor().uninstrument() - # TODO: remove mock.patch when we drop Python 3.9 support - with mock.patch( - "opentelemetry.instrumentation.aiokafka.iscoroutinefunction" - ) as iscoro: - iscoro.side_effect = is_async_produce_hook_mock - - AIOKafkaInstrumentor().instrument( - tracer_provider=self.tracer_provider, - async_produce_hook=async_produce_hook_mock, - ) + AIOKafkaInstrumentor().instrument( + tracer_provider=self.tracer_provider, + async_produce_hook=async_produce_hook_mock, + ) producer = await self.producer_factory() self.addAsyncCleanup(producer.stop) diff --git a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml index 13bf30b54cd..37327d50edc 100644 --- a/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aiopg/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry aiopg instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml index 24e3debff17..36ffeba0bc8 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asgi/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "ASGI instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml index b2a3e5c397b..16cc5299653 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncclick/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Async Click instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml index e30dc7821c2..c1a42b4ed1c 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncio/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry instrumentation for asyncio" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py index f964044fc7b..a89134ca9b8 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. import asyncio -import sys -from unittest import skipIf from unittest.mock import patch # pylint: disable=no-name-in-module @@ -44,9 +42,6 @@ def tearDown(self): # Asyncio anext() does not have __name__ attribute, which is used to determine if the coroutine should be traced. # This test is to ensure that the instrumentation does not break when the coroutine does not have __name__ attribute. # Additionally, ensure the coroutine is actually awaited. - @skipIf( - sys.version_info < (3, 10), "anext is only available in Python 3.10+" - ) def test_asyncio_anext(self): async def main(): async def async_gen(): diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml index 589fd11903e..62b83f4b762 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry instrumentation for AsyncPG" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py index 21d4591e0e7..f8c905a2c79 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py +++ b/instrumentation/opentelemetry-instrumentation-asyncpg/tests/test_asyncpg_wrapper.py @@ -106,7 +106,7 @@ async def exec_mock(*args, **kwargs): ) with pytest.raises(StopAsyncIteration): - asyncio.run(crs_iter.__anext__()) + asyncio.run(anext(crs_iter)) spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 2) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml index ba0b4e3e422..e73c3f99262 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry AWS Lambda instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml index f373fd189bf..d649734720d 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Boto3 SQS service tracing for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml index fa5e8850f77..5dd212a31bf 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Botocore instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py index 3ff8ca7f223..4c3295c45d3 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_lambda.py @@ -113,7 +113,7 @@ def _create_lambda_function(self, function_name: str, function_code: str): self.client.create_function( FunctionName=function_name, - Runtime="python3.9", + Runtime="python3.10", Role=role_arn, Handler="lambda_function.lambda_handler", Code={ diff --git a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml index 60200cce006..6b51889b3c1 100644 --- a/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Cassandra instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml index b60271f42b9..21a58ea35e9 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-celery/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Celery Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml index 3e36f50e3e5..2fbcdf19c03 100644 --- a/instrumentation/opentelemetry-instrumentation-click/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-click/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Click instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml index 87ac6c59669..6958b515ad9 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Confluent Kafka instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml index db9d0b053d0..225f9cf97ba 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-dbapi/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Database API instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml index d0d5090ab3b..56c624d3d51 100644 --- a/instrumentation/opentelemetry-instrumentation-django/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-django/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Instrumentation for Django" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt index de46d416348..0ad78d45166 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt @@ -12,6 +12,7 @@ tomli==2.0.1 typing_extensions==4.12.2 wrapt==1.16.0 zipp==3.19.2 +setuptools==79.0.1 ; python_version >= "3.12" -e opentelemetry-instrumentation -e instrumentation/opentelemetry-instrumentation-wsgi -e util/opentelemetry-util-http diff --git a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt index f7d12ec741e..40c6756d835 100644 --- a/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt +++ b/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt @@ -1,5 +1,4 @@ asgiref==3.8.1 -backports.zoneinfo==0.2.1 Deprecated==1.2.14 Django==4.2.17 iniconfig==2.0.0 diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml index 8b44950fc9a..c7b962ae5af 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry elasticsearch instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml index c4a59473d52..5eb789a5c7a 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-falcon/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Falcon instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml index 7159b2a01c5..c76d0f351c4 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry FastAPI Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml index 08a7366e3f0..4b43789e6c1 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Flask instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py index f69470ab9ed..ced6c8c6f7c 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -254,7 +254,6 @@ def response_hook(span: Span, status: str, response_headers: List): --- """ -import sys import weakref from logging import getLogger from time import time_ns @@ -582,14 +581,8 @@ def _teardown_request(exc): try: # For Flask 3.1+, check if this is a streaming response that might # have already been cleaned up to prevent double cleanup - # Only check for streaming in Flask 3.1+ and Python 3.10+ to avoid interference with older versions - is_flask_31_plus = _IS_FLASK_31_PLUS and sys.version_info >= ( - 3, - 10, - ) - is_streaming = False - if is_flask_31_plus: + if _IS_FLASK_31_PLUS: try: # Additional safety check: verify we're in a Flask request context if hasattr(flask, "request") and hasattr( @@ -605,7 +598,7 @@ def _teardown_request(exc): # Not in a proper Flask request context, don't check for streaming is_streaming = False - if is_flask_31_plus and is_streaming: + if _IS_FLASK_31_PLUS and is_streaming: # For Flask 3.1+ streaming responses, ensure OpenTelemetry contexts are cleaned up # This addresses the generator context leak issues documented by Logfire # (open-telemetry/opentelemetry-python#2606) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_flask_compatibility.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_flask_compatibility.py index dcf9b2bdd61..8e1804038b6 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_flask_compatibility.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_flask_compatibility.py @@ -18,7 +18,6 @@ """ import io -import sys import threading import time from unittest import mock, skipIf @@ -297,10 +296,6 @@ def generate(): self.assertEqual(response.status_code, 200) self.assertEqual(response.data, b"Data") - @skipIf( - sys.version_info < (3, 10), - "Flask 3.1+ streaming context cleanup only enabled on Python 3.10+", - ) @skipIf( lambda: ( not __import__( diff --git a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml index adcfa7afd79..17df13ef8ec 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-grpc/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry gRPC instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml index 7b356b50789..f07cca6ca4a 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-httpx/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry HTTPX Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml index ed6cb19b9fc..70f36f5030e 100644 --- a/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-jinja2/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry jinja2 instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml index ac883738d47..141c72c56f2 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Kafka-Python instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml index de216965c81..f14d2e90ead 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-logging/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Logging instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml index e780d5ab297..f58c79a4dd3 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysql/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry MySQL instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml index e732ccb1491..4d2ba6aca39 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry mysqlclient instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml index 5679a9799c6..8c7c6436962 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pika/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry pika instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml index 322e86d2811..ace2acb412d 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry psycopg instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml index 601b6489184..b96dfe23141 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry psycopg2 instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml index 73c9829a31f..fcb0dfd74aa 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry pymemcache instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml index a58af7ec205..759c9b86491 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymongo/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry pymongo instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml index c29c392bebc..a97c708b15b 100644 --- a/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymssql/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry pymssql instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml index 9dfc439e009..43d72e03ff9 100644 --- a/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pymysql/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry PyMySQL instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml index 7d1450e83f0..0268d0cd022 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-pyramid/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Pyramid instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml index 2277a7f8a50..19c5e194f95 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-redis/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Redis instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml index 5e00fa48cfc..199bee6b0f8 100644 --- a/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-remoulade/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Remoulade instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml index d0ddab1e3cd..7f18d26879a 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-requests/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry requests instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml index 1e69d56ac62..34317db4b07 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry SQLAlchemy instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml index b941f926e26..f837ac585d5 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-sqlite3/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry SQLite3 instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml index 518014039bd..298ea6252a2 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-starlette/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Starlette Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt index e1057fed607..280667dffea 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.9 --universal --no-emit-package opentelemetry-api --no-emit-package opentelemetry-semantic-conventions -c dev-requirements.txt instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in -o instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt +# uv pip compile --python 3.10 --universal --no-emit-package opentelemetry-api --no-emit-package opentelemetry-semantic-conventions -c dev-requirements.txt instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in -o instrumentation/opentelemetry-instrumentation-starlette/test-requirements.latest.txt -e instrumentation/opentelemetry-instrumentation-asgi # via # -r instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in @@ -16,11 +16,7 @@ # -r instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in # opentelemetry-instrumentation-asgi # opentelemetry-instrumentation-starlette -anyio==4.5.2 ; python_full_version < '3.9' - # via - # httpx - # starlette -anyio==4.8.0 ; python_full_version >= '3.9' +anyio==4.8.0 # via # httpx # starlette @@ -70,9 +66,7 @@ requests==2.32.3 # -r instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in sniffio==1.3.1 # via anyio -starlette==0.44.0 ; python_full_version < '3.9' - # via opentelemetry-instrumentation-starlette -starlette==0.46.2 ; python_full_version >= '3.9' +starlette==0.46.2 # via opentelemetry-instrumentation-starlette tomli==2.2.1 ; python_full_version < '3.11' # via pytest @@ -82,16 +76,11 @@ typing-extensions==4.12.2 # asgiref # opentelemetry-api # opentelemetry-semantic-conventions - # starlette -urllib3==2.2.3 ; python_full_version < '3.9' - # via requests -urllib3==2.3.0 ; python_full_version >= '3.9' +urllib3==2.3.0 # via requests wrapt==1.14.1 # via opentelemetry-instrumentation -zipp==3.20.2 ; python_full_version < '3.9' - # via importlib-metadata -zipp==3.21.0 ; python_full_version >= '3.9' +zipp==3.21.0 # via importlib-metadata # The following packages were excluded from the output: diff --git a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt index 99fd4853e98..79dbf0ec769 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt +++ b/instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.9 --universal --resolution lowest-direct --no-emit-package opentelemetry-api --no-emit-package opentelemetry-semantic-conventions -c dev-requirements.txt instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in -o instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt +# uv pip compile --python 3.10 --universal --resolution lowest-direct --no-emit-package opentelemetry-api --no-emit-package opentelemetry-semantic-conventions -c dev-requirements.txt instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in -o instrumentation/opentelemetry-instrumentation-starlette/test-requirements.oldest.txt -e instrumentation/opentelemetry-instrumentation-asgi # via # -r instrumentation/opentelemetry-instrumentation-starlette/test-requirements.in @@ -29,10 +29,6 @@ charset-normalizer==3.4.1 # via requests colorama==0.4.6 ; sys_platform == 'win32' # via pytest -deprecated==1.2.14 - # via - # opentelemetry-api - # opentelemetry-semantic-conventions exceptiongroup==1.2.2 ; python_full_version < '3.11' # via # anyio @@ -72,16 +68,16 @@ starlette==0.13.8 # via opentelemetry-instrumentation-starlette tomli==2.2.1 ; python_full_version < '3.11' # via pytest -typing-extensions==4.12.2 ; python_full_version < '3.13' +typing-extensions==4.12.2 # via # anyio # asgiref + # opentelemetry-api + # opentelemetry-semantic-conventions urllib3==2.3.0 # via requests wrapt==1.16.0 - # via - # deprecated - # opentelemetry-instrumentation + # via opentelemetry-instrumentation zipp==3.21.0 # via importlib-metadata diff --git a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml index 0d2aa6d658b..3060eaa03c5 100644 --- a/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-system-metrics/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry System Metrics Instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml index 66e2a1b8d9f..9f5818117b5 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-threading/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Thread context propagation support for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml index 04890fa6077..5dfb3744c37 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tornado/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Tornado instrumentation for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -17,7 +17,6 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml index 5c0ea288b8e..ee743301b07 100644 --- a/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-tortoiseorm/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Instrumentation for Tortoise ORM" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml index 258e28848db..96e96131896 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry urllib instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml index 0e3e2c5f990..8da041e5046 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-urllib3/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry urllib3 instrumentation" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml index 6fcdeb58684..c008090b639 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml +++ b/instrumentation/opentelemetry-instrumentation-wsgi/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "WSGI Middleware for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/opamp/opentelemetry-opamp-client/pyproject.toml b/opamp/opentelemetry-opamp-client/pyproject.toml index 978878c6207..4d223f77ed3 100644 --- a/opamp/opentelemetry-opamp-client/pyproject.toml +++ b/opamp/opentelemetry-opamp-client/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry OpAMP client" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/opamp/opentelemetry-opamp-client/test-requirements.latest.txt b/opamp/opentelemetry-opamp-client/test-requirements.latest.txt index 8c2e2951286..68196f99924 100644 --- a/opamp/opentelemetry-opamp-client/test-requirements.latest.txt +++ b/opamp/opentelemetry-opamp-client/test-requirements.latest.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.9 --universal -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.latest.txt +# uv pip compile --python 3.10 --universal -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.latest.txt --no-emit-package opentelemetry-api -e opamp/opentelemetry-opamp-client # via -r opamp/opentelemetry-opamp-client/test-requirements.in certifi==2025.7.9 @@ -43,7 +43,7 @@ pytest==7.4.4 # -c dev-requirements.txt # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest-vcr -pytest-vcr==1.0.2 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' +pytest-vcr==1.0.2 ; platform_python_implementation != 'PyPy' # via -r opamp/opentelemetry-opamp-client/test-requirements.in pyyaml==6.0.2 # via @@ -71,7 +71,7 @@ uuid-utils==0.11.0 # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # opentelemetry-opamp-client -vcrpy==7.0.0 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' +vcrpy==7.0.0 ; platform_python_implementation != 'PyPy' # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest-vcr @@ -85,3 +85,6 @@ yarl==1.20.1 # vcrpy zipp==3.23.0 # via importlib-metadata + +# The following packages were excluded from the output: +# opentelemetry-api diff --git a/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt b/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt index 2ab1d9826eb..44acbe65ec7 100644 --- a/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt +++ b/opamp/opentelemetry-opamp-client/test-requirements.lowest.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.9 --universal --resolution lowest -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.lowest.txt +# uv pip compile --python 3.10 --universal --resolution lowest -c dev-requirements.txt opamp/opentelemetry-opamp-client/test-requirements.in -o opamp/opentelemetry-opamp-client/test-requirements.lowest.txt --no-emit-package opentelemetry-api -e opamp/opentelemetry-opamp-client # via -r opamp/opentelemetry-opamp-client/test-requirements.in certifi==2017.4.17 @@ -43,7 +43,7 @@ pytest==7.4.4 # -c dev-requirements.txt # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest-vcr -pytest-vcr==1.0.2 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' +pytest-vcr==1.0.2 ; platform_python_implementation != 'PyPy' # via -r opamp/opentelemetry-opamp-client/test-requirements.in pyyaml==6.0.2 # via @@ -68,7 +68,7 @@ uuid-utils==0.11.0 # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # opentelemetry-opamp-client -vcrpy==7.0.0 ; python_full_version >= '3.10' and platform_python_implementation != 'PyPy' +vcrpy==7.0.0 ; platform_python_implementation != 'PyPy' # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # pytest-vcr @@ -81,3 +81,6 @@ yarl==1.20.1 # via # -r opamp/opentelemetry-opamp-client/test-requirements.in # vcrpy + +# The following packages were excluded from the output: +# opentelemetry-api diff --git a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py index 1bb9df6a4cc..745fb63faa1 100644 --- a/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py +++ b/opamp/opentelemetry-opamp-client/tests/opamp/test_e2e.py @@ -13,7 +13,6 @@ # limitations under the License. import logging -import sys from time import sleep from unittest import mock @@ -25,10 +24,6 @@ from opentelemetry._opamp.proto import opamp_pb2 -@pytest.mark.skipif( - sys.version_info < (3, 10), - reason="vcr.py not working with urllib 2 and older Pythons", -) @pytest.mark.vcr() def test_connection_remote_config_status_heartbeat_disconnection(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") @@ -96,10 +91,6 @@ def on_message(self, agent, client, message): ] -@pytest.mark.skipif( - sys.version_info < (3, 10), - reason="vcr.py not working with urllib 2 and older Pythons", -) @pytest.mark.vcr() def test_with_server_not_responding(caplog): caplog.set_level(logging.DEBUG, logger="opentelemetry._opamp.agent") diff --git a/opentelemetry-contrib-instrumentations/pyproject.toml b/opentelemetry-contrib-instrumentations/pyproject.toml index 76713cfe12d..630509a4b2a 100644 --- a/opentelemetry-contrib-instrumentations/pyproject.toml +++ b/opentelemetry-contrib-instrumentations/pyproject.toml @@ -12,7 +12,7 @@ dynamic = [ description = "OpenTelemetry Contrib Instrumentation Packages" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -22,7 +22,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/opentelemetry-distro/pyproject.toml b/opentelemetry-distro/pyproject.toml index 538237ea031..432ed1264d0 100644 --- a/opentelemetry-distro/pyproject.toml +++ b/opentelemetry-distro/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Python Distro" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/opentelemetry-instrumentation/pyproject.toml b/opentelemetry-instrumentation/pyproject.toml index 00de032a445..5a472d774e5 100644 --- a/opentelemetry-instrumentation/pyproject.toml +++ b/opentelemetry-instrumentation/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/processor/opentelemetry-processor-baggage/pyproject.toml b/processor/opentelemetry-processor-baggage/pyproject.toml index 31f8ddfb7a5..f11bbd36094 100644 --- a/processor/opentelemetry-processor-baggage/pyproject.toml +++ b/processor/opentelemetry-processor-baggage/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry Baggage Span Processor" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml index 0f7240efa6a..66f7d69550f 100644 --- a/propagator/opentelemetry-propagator-aws-xray/pyproject.toml +++ b/propagator/opentelemetry-propagator-aws-xray/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "AWS X-Ray Propagator for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml index 74f15033319..3569d4842af 100644 --- a/propagator/opentelemetry-propagator-ot-trace/pyproject.toml +++ b/propagator/opentelemetry-propagator-ot-trace/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OT Trace Propagator for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/pyproject.toml b/pyproject.toml index c877d5f0380..92cfe8b5d20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ [project] name = "opentelemetry-python-contrib" version = "0.0.0" # This is not used. -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ "opentelemetry-api", "opentelemetry-sdk", @@ -154,7 +154,7 @@ members = [ [tool.ruff] # https://docs.astral.sh/ruff/configuration/ -target-version = "py39" +target-version = "py310" line-length = 79 extend-exclude = ["_template", "*_pb2*.py*"] output-format = "concise" @@ -196,7 +196,7 @@ known-third-party = [ typeCheckingMode = "strict" reportUnnecessaryTypeIgnoreComment = true reportMissingTypeStubs = false -pythonVersion = "3.9" +pythonVersion = "3.10" reportPrivateUsage = false # Ignore private attributes added by instrumentation packages. # Add progressively instrumentation packages here. include = [ diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index b6c27d71323..99c5cebb96f 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Azure Resource Detector for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/resource/opentelemetry-resource-detector-containerid/pyproject.toml b/resource/opentelemetry-resource-detector-containerid/pyproject.toml index 46875adb09f..de1ec197179 100644 --- a/resource/opentelemetry-resource-detector-containerid/pyproject.toml +++ b/resource/opentelemetry-resource-detector-containerid/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Container Resource Detector for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml index 10e18b9ef11..716c3f1204a 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml +++ b/sdk-extension/opentelemetry-sdk-extension-aws/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "AWS SDK extension for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/tox.ini b/tox.ini index 8d8d86305b7..1f2ca7f8e90 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ envlist = ; for specifying supported Python versions per package. ; instrumentation-openai - py3{9,10,11,12,13,14}-test-instrumentation-openai-v2-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-openai-v2-{oldest,latest} py313-test-instrumentation-openai-v2-pydantic1 pypy3-test-instrumentation-openai-v2-{oldest,latest} lint-instrumentation-openai-v2 @@ -19,19 +19,19 @@ envlist = lint-instrumentation-openai_agents-v2 ; instrumentation-vertexai - py3{9,10,11,12,13,14}-test-instrumentation-vertexai-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-vertexai-{oldest,latest} # Disabling pypy3 as shapely does not have wheels and fails to compile # pypy3-test-instrumentation-vertexai-{oldest,latest} lint-instrumentation-vertexai ; instrumentation-google-genai - py3{9,10,11,12,13,14}-test-instrumentation-google-genai-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-google-genai-{oldest,latest} # Disabling pypy3 as shapely does not have wheels and fails to compile # pypy3-test-instrumentation-google-genai-{0,1} lint-instrumentation-google-genai ; instrumentation-anthropic - py3{9,10,11,12,13,14}-test-instrumentation-anthropic-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-anthropic-{oldest,latest} # Disabling pypy3 as jiter (anthropic dep) requires PyPy 3.11+ # pypy3-test-instrumentation-anthropic-{oldest,latest} lint-instrumentation-anthropic @@ -43,60 +43,60 @@ envlist = lint-instrumentation-claude-agent-sdk ; opentelemetry-resource-detector-containerid - py3{9,10,11,12,13,14}-test-resource-detector-containerid + py3{10,11,12,13,14}-test-resource-detector-containerid pypy3-test-resource-detector-containerid lint-resource-detector-containerid ; opentelemetry-resource-detector-azure - py3{9,10,11,12,13,14}-test-resource-detector-azure-{0,1} + py3{10,11,12,13,14}-test-resource-detector-azure-{0,1} pypy3-test-resource-detector-azure-{0,1} lint-resource-detector-azure ; opentelemetry-sdk-extension-aws - py3{9,10,11,12,13,14}-test-sdk-extension-aws-{0,1} + py3{10,11,12,13,14}-test-sdk-extension-aws-{0,1} pypy3-test-sdk-extension-aws-{0,1} lint-sdk-extension-aws benchmark-sdk-extension-aws ; opentelemetry-distro - py3{9,10,11,12,13,14}-test-distro + py3{10,11,12,13,14}-test-distro pypy3-test-distro lint-distro ; opentelemetry-instrumentation - py3{9,10,11,12,13,14}-test-opentelemetry-instrumentation-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-opentelemetry-instrumentation-{wrapt1,wrapt2} pypy3-test-opentelemetry-instrumentation-wrapt2 lint-opentelemetry-instrumentation ; opentelemetry-instrumentation-aiohttp-client - py3{9,10,11,12,13,14}-test-instrumentation-aiohttp-client + py3{10,11,12,13,14}-test-instrumentation-aiohttp-client pypy3-test-instrumentation-aiohttp-client lint-instrumentation-aiohttp-client ; opentelemetry-instrumentation-aiohttp-server - py3{9,10,11,12,13,14}-test-instrumentation-aiohttp-server + py3{10,11,12,13,14}-test-instrumentation-aiohttp-server pypy3-test-instrumentation-aiohttp-server lint-instrumentation-aiohttp-server ; opentelemetry-instrumentation-aiopg - py3{9,10,11,12,13,14}-test-instrumentation-aiopg-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-aiopg-{wrapt1,wrapt2} ; instrumentation-aiopg intentionally excluded from pypy3 lint-instrumentation-aiopg ; opentelemetry-instrumentation-aws-lambda - py3{9,10,11,12,13,14}-test-instrumentation-aws-lambda + py3{10,11,12,13,14}-test-instrumentation-aws-lambda pypy3-test-instrumentation-aws-lambda lint-instrumentation-aws-lambda ; opentelemetry-instrumentation-botocore - py3{9,10,11,12,13,14}-test-instrumentation-botocore-{0,1}-{wrapt1,wrapt2} - py3{9,10,11,12,13,14}-test-instrumentation-botocore-{2,3} + py3{10,11,12,13,14}-test-instrumentation-botocore-{0,1}-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-botocore-{2,3} ; FIXME: see https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1736 ; pypy3-test-instrumentation-botocore lint-instrumentation-botocore ; opentelemetry-instrumentation-boto3sqs - py3{9,10,11,12,13,14}-test-instrumentation-boto3sqs + py3{10,11,12,13,14}-test-instrumentation-boto3sqs pypy3-test-instrumentation-boto3sqs lint-instrumentation-boto3sqs @@ -108,26 +108,25 @@ envlist = ; below mean these dependencies are being used: ; 0: django~=2.0 ; 1: django~=3.0 - ; 2: django>=4.0b1,<5.0 backports.zoneinfo==0.2.1 + ; 2: django~=4.0 ; 3: django>=5.2<6.0 - py3{9}-test-instrumentation-django-{0,1,2} - py3{10,11,12}-test-instrumentation-django-{1,3} + py3{10,11,12}-test-instrumentation-django-{0,1,2,3} py3{13,14}-test-instrumentation-django-3 - pypy3-test-instrumentation-django-{0,1} + pypy3-test-instrumentation-django-{0,1,2,3} lint-instrumentation-django ; opentelemetry-instrumentation-dbapi - py3{9,10,11,12,13,14}-test-instrumentation-dbapi-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-dbapi-{wrapt1,wrapt2} pypy3-test-instrumentation-dbapi-wrapt2 lint-instrumentation-dbapi ; opentelemetry-instrumentation-asyncclick - py3{9,10,11,12,13,14}-test-instrumentation-asyncclick + py3{10,11,12,13,14}-test-instrumentation-asyncclick pypy3-test-instrumentation-asyncclick lint-instrumentation-asyncclick ; opentelemetry-instrumentation-click - py3{9,10,11,12,13,14}-test-instrumentation-click + py3{10,11,12,13,14}-test-instrumentation-click pypy3-test-instrumentation-click lint-instrumentation-click @@ -137,28 +136,25 @@ envlist = ; 0: elasticsearch-dsl==6.4.0 elasticsearch==6.8.2 ; 1: elasticsearch-dsl==7.4.1 elasticsearch==7.17.9 ; 2: elasticsearch-dsl==8.13.1 elasticsearch==8.13.1 - py3{9,10,11,12,13,14}-test-instrumentation-elasticsearch-{0,1,2} + py3{10,11,12,13,14}-test-instrumentation-elasticsearch-{0,1,2} pypy3-test-instrumentation-elasticsearch-{0,1,2} lint-instrumentation-elasticsearch ; opentelemetry-instrumentation-falcon - ; py310 does not work with falcon 1 - ; py3{9} will be dropped for falcon 4 + ; TODO: py310 does not work with falcon 1 - Drop requirements-0.txt and bump supported version to >2 ; The numbers at the end of the environment names ; below mean these dependencies are being used: - ; 0: falcon ==1.4.1 ; 1: falcon >=2.0.0,<3.0.0 ; 2: falcon >=3.0.0,<3.1.2 ; 3: falcon >=3.1.2,<4.0.0 ; 4: falcon >=4.0.0,<5.0.0 - py3{9}-test-instrumentation-falcon-{0,1,2,3} py3{10,11,12}-test-instrumentation-falcon-{1,2,3,4} py3{13,14}-test-instrumentation-falcon-4 - pypy3-test-instrumentation-falcon-{0,1,2,3,4} + pypy3-test-instrumentation-falcon-{1,2,3,4} lint-instrumentation-falcon ; opentelemetry-instrumentation-fastapi - py3{9,10,11,12,13,14}-test-instrumentation-fastapi + py3{10,11,12,13,14}-test-instrumentation-fastapi pypy3-test-instrumentation-fastapi lint-instrumentation-fastapi @@ -169,12 +165,12 @@ envlist = ; 1: Flask ==2.2.0 Werkzeug <3.0.0 ; 2: Flask >=3.0.0 Werkzeug >=3.0.0 ; 3: Flask >=3.1.0 Werkzeug >=3.1.0 - py3{9,10,11,12,13,14}-test-instrumentation-flask-{0,1,2,3} + py3{10,11,12,13,14}-test-instrumentation-flask-{0,1,2,3} pypy3-test-instrumentation-flask-{0,1} lint-instrumentation-flask ; opentelemetry-instrumentation-urllib - py3{9,10,11,12,13,14}-test-instrumentation-urllib + py3{10,11,12,13,14}-test-instrumentation-urllib pypy3-test-instrumentation-urllib lint-instrumentation-urllib @@ -184,40 +180,40 @@ envlist = ; 0: urllib3 >=1.0.0,<2.0.0 ; 1: urllib3 >=2.0.0,<3.0.0 ; TODO #4200 Add py314 testing after replacing httpretty -- problem with https tests in 3.14 - py3{9,10,11,12,13}-test-instrumentation-urllib3-{0,1} + py3{10,11,12,13}-test-instrumentation-urllib3-{0,1} pypy3-test-instrumentation-urllib3-{0,1} lint-instrumentation-urllib3 ; opentelemetry-instrumentation-requests - py3{9,10,11,12,13,14}-test-instrumentation-requests + py3{10,11,12,13,14}-test-instrumentation-requests ;pypy3-test-instrumentation-requests lint-instrumentation-requests ; opentelemetry-instrumentation-starlette - py3{9,10,11,12,13,14}-test-instrumentation-starlette-{oldest,latest} + py3{10,11,12,13,14}-test-instrumentation-starlette-{oldest,latest} pypy3-test-instrumentation-starlette-{oldest,latest} lint-instrumentation-starlette ; opentelemetry-instrumentation-jinja2 - py3{9,10,11,12,13,14}-test-instrumentation-jinja2 + py3{10,11,12,13,14}-test-instrumentation-jinja2 pypy3-test-instrumentation-jinja2 lint-instrumentation-jinja2 ; opentelemetry-instrumentation-logging - py3{9,10,11,12,13,14}-test-instrumentation-logging + py3{10,11,12,13,14}-test-instrumentation-logging pypy3-test-instrumentation-logging lint-instrumentation-logging benchmark-instrumentation-logging ; opentelemetry-exporter-richconsole - py3{9,10,11,12,13,14}-test-exporter-richconsole + py3{10,11,12,13,14}-test-exporter-richconsole pypy3-test-exporter-richconsole lint-exporter-richconsole ; opentelemetry-exporter-prometheus-remote-write - py3{9,10,11,12,13,14}-test-exporter-prometheus-remote-write + py3{10,11,12,13,14}-test-exporter-prometheus-remote-write # excluded from pypy3 due to missing wheel - pypy310-test-exporter-prometheus-remote-write + pypy3-test-exporter-prometheus-remote-write lint-exporter-prometheus-remote-write ; opentelemetry-instrumentation-mysql @@ -225,12 +221,12 @@ envlist = ; below mean these dependencies are being used: ; 0: mysql-connector-python >=8.0.0,<9.0.0 ; 1: mysql-connector-python ~=9.0.0 - py3{9,10,11,12,13,14}-test-instrumentation-mysql-{0,1} + py3{10,11,12,13,14}-test-instrumentation-mysql-{0,1} pypy3-test-instrumentation-mysql-{0,1} lint-instrumentation-mysql ; opentelemetry-instrumentation-mysqlclient - py3{9,10,11,12,13,14}-test-instrumentation-mysqlclient + py3{10,11,12,13,14}-test-instrumentation-mysqlclient pypy3-test-instrumentation-mysqlclient ; prerequisite: follow the instructions here ; https://github.com/PyMySQL/mysqlclient#install @@ -238,13 +234,13 @@ envlist = lint-instrumentation-mysqlclient ; opentelemetry-instrumentation-psycopg2 - py3{9,10,11,12,13,14}-test-instrumentation-psycopg2 - py3{9,10,11,12,13,14}-test-instrumentation-psycopg2-binary + py3{10,11,12,13,14}-test-instrumentation-psycopg2 + py3{10,11,12,13,14}-test-instrumentation-psycopg2-binary ; ext-psycopg2 intentionally excluded from pypy3 lint-instrumentation-psycopg2 ; opentelemetry-instrumentation-psycopg - py3{9,10,11,12,13,14}-test-instrumentation-psycopg + py3{10,11,12,13,14}-test-instrumentation-psycopg pypy3-test-instrumentation-psycopg lint-instrumentation-psycopg @@ -256,48 +252,48 @@ envlist = ; 2: pymemcache >3.0.0,<3.4.2 ; 3: pymemcache ==3.4.2 ; 4: pymemcache ==4.0.0 - py3{9,10,11,12,13,14}-test-instrumentation-pymemcache-{0,1,2,3,4} + py3{10,11,12,13,14}-test-instrumentation-pymemcache-{0,1,2,3,4} pypy3-test-instrumentation-pymemcache-{0,1,2,3,4} lint-instrumentation-pymemcache ; opentelemetry-instrumentation-pymongo - py3{9,10,11,12,13,14}-test-instrumentation-pymongo + py3{10,11,12,13,14}-test-instrumentation-pymongo pypy3-test-instrumentation-pymongo lint-instrumentation-pymongo ; opentelemetry-instrumentation-pymysql - py3{9,10,11,12,13,14}-test-instrumentation-pymysql + py3{10,11,12,13,14}-test-instrumentation-pymysql pypy3-test-instrumentation-pymysql lint-instrumentation-pymysql ; opentelemetry-instrumentation-pymssql - py3{9,10,11,12,13,14}-test-instrumentation-pymssql + py3{10,11,12,13,14}-test-instrumentation-pymssql ; pymssql has no support for pypy: see https://github.com/pymssql/pymssql/pull/517 ; pypy3-test-instrumentation-pymssql lint-instrumentation-pymssql ; opentelemetry-instrumentation-pyramid - py3{9,10,11,12,13,14}-test-instrumentation-pyramid + py3{10,11,12,13,14}-test-instrumentation-pyramid pypy3-test-instrumentation-pyramid lint-instrumentation-pyramid ; opentelemetry-instrumentation-asgi - py3{9,10,11,12,13,14}-test-instrumentation-asgi + py3{10,11,12,13,14}-test-instrumentation-asgi pypy3-test-instrumentation-asgi lint-instrumentation-asgi ; opentelemetry-instrumentation-asyncpg - py3{9,10,11,12,13,14}-test-instrumentation-asyncpg-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-asyncpg-{wrapt1,wrapt2} ; ext-asyncpg intentionally excluded from pypy3 lint-instrumentation-asyncpg ; opentelemetry-instrumentation-sqlite3 - py3{9,10,11,12,13,14}-test-instrumentation-sqlite3 + py3{10,11,12,13,14}-test-instrumentation-sqlite3 pypy3-test-instrumentation-sqlite3 lint-instrumentation-sqlite3 ; opentelemetry-instrumentation-wsgi - py3{9,10,11,12,13,14}-test-instrumentation-wsgi + py3{10,11,12,13,14}-test-instrumentation-wsgi pypy3-test-instrumentation-wsgi lint-instrumentation-wsgi @@ -307,53 +303,53 @@ envlist = ; 0: grpcio==1.62.0 ; 1: grpcio==1.75.1 ; TODO #4201 simplify tests-requirements here to use latest|oldest testing pattern - py3{9,10,11,12}-test-instrumentation-grpc-{0,1}-{wrapt1,wrapt2} + py3{10,11,12}-test-instrumentation-grpc-{0,1}-{wrapt1,wrapt2} py3{13,14}-test-instrumentation-grpc-1-{wrapt1,wrapt2} lint-instrumentation-grpc ; opentelemetry-instrumentation-sqlalchemy ; The numbers at the end of the environment names ; below mean these dependencies are being used: - ; 0: sqlalchemy>=1.1,<1.2 + ; 0: sqlalchemy>=1.1,<1.2 - TODO: drop test-requirements-0.txt and update to >=1.4,<2.0 once 1.1 support is removed ; 1: sqlalchemy~=1.4 aiosqlite ; 2: sqlalchemy~=2.0.0 - py3{9,10,11,12,13}-test-instrumentation-sqlalchemy-{1,2} + py3{10,11,12,13}-test-instrumentation-sqlalchemy-{1,2} py314-test-instrumentation-sqlalchemy-2 - pypy3-test-instrumentation-sqlalchemy-{0,1,2} + pypy3-test-instrumentation-sqlalchemy-{1,2} lint-instrumentation-sqlalchemy ; opentelemetry-instrumentation-redis - py3{9,10,11,12,13,14}-test-instrumentation-redis + py3{10,11,12,13,14}-test-instrumentation-redis pypy3-test-instrumentation-redis lint-instrumentation-redis ; opentelemetry-instrumentation-remoulade - py3{9,10,11,12,13,14}-test-instrumentation-remoulade + py3{10,11,12,13,14}-test-instrumentation-remoulade ; instrumentation-remoulade intentionally excluded from pypy3 lint-instrumentation-remoulade ; opentelemetry-instrumentation-celery - py3{9,10,11,12,13,14}-test-instrumentation-celery + py3{10,11,12,13,14}-test-instrumentation-celery pypy3-test-instrumentation-celery lint-instrumentation-celery ; opentelemetry-instrumentation-system-metrics - py3{9,10,11,12,13,14}-test-instrumentation-system-metrics + py3{10,11,12,13,14}-test-instrumentation-system-metrics pypy3-test-instrumentation-system-metrics lint-instrumentation-system-metrics ; opentelemetry-instrumentation-threading - py3{9,10,11,12,13,14}-test-instrumentation-threading + py3{10,11,12,13,14}-test-instrumentation-threading pypy3-test-instrumentation-threading lint-instrumentation-threading ; opentelemetry-instrumentation-tornado - py3{9,10,11,12,13,14}-test-instrumentation-tornado + py3{10,11,12,13,14}-test-instrumentation-tornado pypy3-test-instrumentation-tornado lint-instrumentation-tornado ; opentelemetry-instrumentation-tortoiseorm - py3{9,10,11,12,13,14}-test-instrumentation-tortoiseorm + py3{10,11,12,13,14}-test-instrumentation-tortoiseorm pypy3-test-instrumentation-tortoiseorm lint-instrumentation-tortoiseorm @@ -362,33 +358,33 @@ envlist = ; below mean these dependencies are being used: ; 0: httpx>=0.18.0,<0.19.0 respx~=0.17.0 ; 1: httpx>=0.19.0 respx~=0.20.1 - py3{9,10,11,12}-test-instrumentation-httpx-{0,1}-{wrapt1,wrapt2} + py3{10,11,12}-test-instrumentation-httpx-{0,1}-{wrapt1,wrapt2} py3{13,14}-test-instrumentation-httpx-1-{wrapt1,wrapt2} pypy3-test-instrumentation-httpx-{0,1}-wrapt2 lint-instrumentation-httpx ; opentelemetry-util-http - py3{9,10,11,12,13,14}-test-util-http + py3{10,11,12,13,14}-test-util-http pypy3-test-util-http lint-util-http ; opentelemetry-exporter-credential-provider-gcp - py3{9,10,11,12,13,14}-test-exporter-credential-provider-gcp + py3{10,11,12,13,14}-test-exporter-credential-provider-gcp lint-exporter-credential-provider-gcp ; opentelemetry-util-genai - py3{9,10,11,12,13,14}-test-util-genai + py3{10,11,12,13,14}-test-util-genai pypy3-test-util-genai lint-util-genai ; opentelemetry-propagator-aws-xray - py3{9,10,11,12,13,14}-test-propagator-aws-xray-{0,1} + py3{10,11,12,13,14}-test-propagator-aws-xray-{0,1} pypy3-test-propagator-aws-xray-{0,1} lint-propagator-aws-xray benchmark-propagator-aws-xray ; opentelemetry-propagator-ot-trace - py3{9,10,11,12,13,14}-test-propagator-ot-trace + py3{10,11,12,13,14}-test-propagator-ot-trace pypy3-test-propagator-ot-trace lint-propagator-ot-trace @@ -397,7 +393,7 @@ envlist = ; below mean these dependencies are being used: ; 0: pika>=0.12.0,<1.0.0 ; 1: pika>=1.0.0 - py3{9,10,11,12,13,14}-test-instrumentation-sio-pika-{0,1}-{wrapt1,wrapt2} + py3{10,11,12,13,14}-test-instrumentation-sio-pika-{0,1}-{wrapt1,wrapt2} pypy3-test-instrumentation-sio-pika-{0,1}-wrapt2 lint-instrumentation-sio-pika @@ -408,43 +404,43 @@ envlist = ; 1: aio_pika==8.3.0 ; 2: aio_pika==9.0.5 ; 3: aio_pika==9.4.1 - py3{9,10,11,12,13,14}-test-instrumentation-aio-pika-{0,1,2,3} + py3{10,11,12,13,14}-test-instrumentation-aio-pika-{0,1,2,3} pypy3-test-instrumentation-aio-pika-{0,1,2,3} lint-instrumentation-aio-pika ; opentelemetry-instrumentation-aiokafka - py3{9,10,11,12,13,14}-test-instrumentation-aiokafka + py3{10,11,12,13,14}-test-instrumentation-aiokafka pypy3-test-instrumentation-aiokafka lint-instrumentation-aiokafka ; opentelemetry-instrumentation-kafka-python - py3{9,10,11}-test-instrumentation-kafka-python - py3{9,10,11,12,13,14}-test-instrumentation-kafka-pythonng + py3{10,11}-test-instrumentation-kafka-python + py3{10,11,12,13,14}-test-instrumentation-kafka-pythonng pypy3-test-instrumentation-kafka-python pypy3-test-instrumentation-kafka-pythonng lint-instrumentation-kafka-python ; opentelemetry-instrumentation-confluent-kafka - py3{9,10,11,12,13,14}-test-instrumentation-confluent-kafka + py3{10,11,12,13,14}-test-instrumentation-confluent-kafka lint-instrumentation-confluent-kafka ; opentelemetry-instrumentation-asyncio - py3{9,10,11,12,13,14}-test-instrumentation-asyncio + py3{10,11,12,13,14}-test-instrumentation-asyncio lint-instrumentation-asyncio ; opentelemetry-instrumentation-cassandra - py3{9,10,11,12,13,14}-test-instrumentation-cassandra-{driver,scylla} + py3{10,11,12,13,14}-test-instrumentation-cassandra-{driver,scylla} pypy3-test-instrumentation-cassandra-scylla lint-instrumentation-cassandra ; opentelemetry-processor-baggage - py3{9,10,11,12,13,14}-test-processor-baggage + py3{10,11,12,13,14}-test-processor-baggage pypy3-test-processor-baggage ; requires snappy headers to be available on the system lint-processor-baggage ; opentelemetry-opamp-client - py3{9,10,11,12,13,14}-test-opamp-client-{latest,lowest} + py3{10,11,12,13,14}-test-opamp-client-{latest,lowest} ; https://github.com/kevin1024/vcrpy/pull/775#issuecomment-1847849962 ; pypy3-test-opamp-client lint-opamp-client @@ -515,7 +511,6 @@ deps = asgi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/test-requirements.txt celery: {[testenv]test_deps} - py3{9}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-0.txt py3{10,11,12,13,14}-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt pypy3-test-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt lint-instrumentation-celery: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-celery/test-requirements-1.txt @@ -617,13 +612,10 @@ deps = lint-instrumentation-dbapi: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi/test-requirements-wrapt2.txt django: {[testenv]test_deps} - py3{9}-test-instrumentation-django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt - py3{9}-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - py3{9}-test-instrumentation-django-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt - py3{10,11,12}-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt - py3{10,11,12,13,14}-test-instrumentation-django-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt - pypy3-test-instrumentation-django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt - pypy3-test-instrumentation-django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt + django-0: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-0.txt + django-1: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-1.txt + django-2: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-2.txt + django-3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt lint-instrumentation-django: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-django/test-requirements-3.txt fastapi: {[testenv]test_deps} @@ -649,7 +641,6 @@ deps = pymongo: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo/test-requirements.txt psycopg: {[testenv]test_deps} - py3{9}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-0.txt py3{10,11,12,13,14}-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt pypy3-test-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt lint-instrumentation-psycopg: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-psycopg/test-requirements-1.txt diff --git a/util/opentelemetry-util-genai/pyproject.toml b/util/opentelemetry-util-genai/pyproject.toml index f8705369c2e..be3ba572385 100644 --- a/util/opentelemetry-util-genai/pyproject.toml +++ b/util/opentelemetry-util-genai/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "OpenTelemetry GenAI Utils" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/util/opentelemetry-util-http/pyproject.toml b/util/opentelemetry-util-http/pyproject.toml index 87d963cf01c..48170a2f319 100644 --- a/util/opentelemetry-util-http/pyproject.toml +++ b/util/opentelemetry-util-http/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "Web util for OpenTelemetry" readme = "README.rst" license = "Apache-2.0" -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, ] @@ -18,7 +18,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", From 07758b082fd99d3b1ca60a4f3b7f0a3b33cce255 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Tue, 14 Apr 2026 10:20:41 +0200 Subject: [PATCH 71/78] Add AGENTS.md with project structure and commands (#4233) * Add CLAUDE.md with project structure and commands * Add AGENTS.md symlink to CLAUDE.md * Move guidance to AGENTS.md and address review feedback - Move main content from CLAUDE.md to AGENTS.md so all AI agents (not only Claude) pick up the guidance; CLAUDE.md now just references it via `@AGENTS.md`. - Add general rules, PR scoping, and `Assisted-by:` commit trailer guidance (inspired by the Collector's AGENTS.md). - Clarify that only instrumentation packages live under `src/opentelemetry/instrumentation/{name}/`; other package types use their own namespace. --------- Co-authored-by: Riccardo Magliocchetti --- AGENTS.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + 2 files changed, 70 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..7467033607f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,69 @@ +# OpenTelemetry Python Contrib + +This file is here to steer AI assisted PRs towards being high quality and valuable contributions +that do not create excessive maintainer burden. + +Monorepo with 50+ OpenTelemetry instrumentation packages for Python. + +## General Rules and Guidelines + +The most important rule is not to post comments on issues or PRs that are AI-generated. Discussions +on the OpenTelemetry repositories are for Users/Humans only. + +Follow the PR scoping guidance in [CONTRIBUTING.md](CONTRIBUTING.md). Keep AI-assisted PRs tightly +isolated to the requested change and never include unrelated cleanup or opportunistic improvements +unless they are strictly necessary for correctness. + +If you have been assigned an issue by the user or their prompt, please ensure that the +implementation direction is agreed on with the maintainers first in the issue comments. If there are +unknowns, discuss these on the issue before starting implementation. Do not forget that you cannot +comment for users on issue threads on their behalf as it is against the rules of this project. + +## Structure + +- `instrumentation/` - instrumentation packages (Flask, Django, FastAPI, gRPC, databases, etc.) +- `instrumentation-genai/` - GenAI instrumentations (Anthropic, Vertex AI, LangChain, etc.) +- `util/` - shared utilities (`util-http`, `util-genai`) +- `exporter/` - custom exporters +- `propagator/` - context propagators + +Instrumentation packages live under `src/opentelemetry/instrumentation/{name}/` with their own +`pyproject.toml` and `tests/`. Other package types follow the equivalent layout under their own +namespace (e.g. `src/opentelemetry/util/{name}/`, `src/opentelemetry/exporter/{name}/`). + +## Commands + +```sh +# Install all packages and dev tools +uv sync --frozen --all-packages + +# Lint (runs ruff via pre-commit) +uv run pre-commit run ruff --all-files + +# Test a specific package (append -0, -1, etc. for version variants) +uv run tox -e py312-test-instrumentation-flask-0 + +# Type check +uv run tox -e typecheck +``` + +## Guidelines + +- Each package has its own `pyproject.toml` with version, dependencies, and entry points. +- The monorepo uses `uv` workspaces. +- `tox.ini` defines the test matrix - check it for available test environments. +- Do not add `type: ignore` comments. If a type error arises, solve it properly or write a follow-up plan to address it in another PR. +- Whenever applicable, all code changes should have tests that actually validate the changes. + +## Commit formatting + +We appreciate it if users disclose the use of AI tools when the significant part of a commit is +taken from a tool without changes. When making a commit this should be disclosed through an +`Assisted-by:` commit message trailer. + +Examples: + +``` +Assisted-by: ChatGPT 5.2 +Assisted-by: Claude Opus 4.6 +``` diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..43c994c2d36 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md From 7edfc3a3a9ac444f410964f3f1adb0e7bc248a9a Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 14 Apr 2026 14:48:01 +0200 Subject: [PATCH 72/78] scripts: drop update_sha (#4430) It's buggy and unused. --- scripts/update_sha.py | 66 ------------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 scripts/update_sha.py diff --git a/scripts/update_sha.py b/scripts/update_sha.py deleted file mode 100644 index c63b9eda9bf..00000000000 --- a/scripts/update_sha.py +++ /dev/null @@ -1,66 +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. - -# pylint: disable=import-error,unspecified-encoding - -import argparse - -import requests -from ruamel.yaml import YAML - -API_URL = ( - "https://api.github.com/repos/open-telemetry/opentelemetry-python/commits/" -) -workflow_files = [ - ".github/workflows/test_0.yml" - ".github/workflows/test_1.yml" - ".github/workflows/misc_0.yml" - ".github/workflows/lint_0.yml" -] - - -def get_sha(branch): - url = API_URL + branch - response = requests.get(url, timeout=15) - response.raise_for_status() - return response.json()["sha"] - - -def update_sha(sha): - yaml = YAML() - yaml.preserve_quotes = True - for workflow_file in workflow_files: - with open(workflow_file, "r") as file: - workflow = yaml.load(file) - workflow["env"]["CORE_REPO_SHA"] = sha - with open(workflow_file, "w") as file: - yaml.dump(workflow, file) - - -def main(): - args = parse_args() - sha = get_sha(args.branch) - update_sha(sha) - - -def parse_args(): - parser = argparse.ArgumentParser( - description="Updates the SHA in the workflow file" - ) - parser.add_argument("-b", "--branch", help="branch to use") - return parser.parse_args() - - -if __name__ == "__main__": - main() From dc78bd0d868df6416282b8dc29bd4fc533c38f99 Mon Sep 17 00:00:00 2001 From: Sri Kaaviya <107148069+srikaaviya@users.noreply.github.com> Date: Tue, 14 Apr 2026 07:56:58 -0700 Subject: [PATCH 73/78] Fix pylint false positives for ThreadPoolExecutor (#4244) * Bump pylint to 4.0.5 to fix Python 3.14 concurrent.futures false positives * Fix too-many-positional-arguments pylint failures - Add max-positional-arguments=10, Add pylint: disable=too-many-positional-arguments to functions that legitimately exceed the limit * Bump max-positional-arguments to 12 and remove unnecessary disable comments * Address review comments: fix CHANGELOG, remove stale pylintrc comment, add openai-agents disable * Fix formatting: restore blank line in CHANGELOG and remove extra blank line in .pylintrc * Update processor.py * Update test_botocore_bedrock.py --------- Co-authored-by: Riccardo Magliocchetti --- .pylintrc | 7 +++---- CHANGELOG.md | 5 +++++ dev-requirements.txt | 2 +- .../instrumentation/openai_agents/span_processor.py | 1 + .../opentelemetry/instrumentation/asgi/__init__.py | 2 +- .../tests/test_asyncio_run_coroutine_threadsafe.py | 4 +--- .../tests/test_botocore_bedrock.py | 11 ----------- .../tests/test_threading.py | 2 +- .../opentelemetry/instrumentation/urllib3/__init__.py | 2 +- .../src/opentelemetry/processor/baggage/processor.py | 2 +- .../sdk/extension/aws/trace/sampler/_sampling_rule.py | 2 +- .../util/genai/_upload/completion_hook.py | 2 +- 12 files changed, 17 insertions(+), 25 deletions(-) diff --git a/.pylintrc b/.pylintrc index 17f53f20985..d3a4723112e 100644 --- a/.pylintrc +++ b/.pylintrc @@ -37,10 +37,6 @@ persistent=yes # Specify a configuration file. #rcfile= -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no @@ -463,6 +459,9 @@ valid-metaclass-classmethod-first-arg=cls # Maximum number of arguments for function / method. max-args=5 +# Maximum number of positional arguments for function / method. +max-positional-arguments=12 + # Maximum number of attributes for a class (see R0902). max-attributes=7 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dca6b771e9..8818f8b0700 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Bump `pylint` to `4.0.5` + ([#4244](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4244)) + ### Breaking changes - Drop Python 3.9 support diff --git a/dev-requirements.txt b/dev-requirements.txt index 29325a6d352..28b7f814871 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,4 +1,4 @@ -pylint==3.0.2 +pylint==4.0.5 httpretty==1.1.4 pyright==v1.1.404 sphinx==7.1.2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py index 74be6637010..55539a4931c 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py @@ -426,6 +426,7 @@ def get_span_name( class GenAISemanticProcessor(TracingProcessor): """Trace processor adding GenAI semantic convention attributes with metrics.""" + # pylint: disable=too-many-positional-arguments def __init__( self, tracer: Optional[Tracer] = None, diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index e28315f502e..8e7106010fd 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -586,7 +586,7 @@ class OpenTelemetryMiddleware: exclude_spans: Optionally exclude HTTP `send` and/or `receive` spans from the trace. """ - # pylint: disable=too-many-branches + # pylint: disable=too-many-branches,too-many-positional-arguments def __init__( self, app, diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_run_coroutine_threadsafe.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_run_coroutine_threadsafe.py index d612076dbf9..fdf4bcb353d 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_run_coroutine_threadsafe.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_run_coroutine_threadsafe.py @@ -13,9 +13,7 @@ # limitations under the License. import asyncio import threading -from concurrent.futures import ( # pylint: disable=no-name-in-module; TODO #4199 - ThreadPoolExecutor, -) +from concurrent.futures import ThreadPoolExecutor from unittest.mock import patch # pylint: disable=no-name-in-module diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py index ef0146314f1..bf8a2ac2429 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_bedrock.py @@ -1487,7 +1487,6 @@ def test_invoke_model_with_content( finish_reason = "length" else: pytest.xfail("model family not handled: {model_family}") - return assert_message_in_logs(logs[0], "gen_ai.user.message", user_content, span) @@ -1628,7 +1627,6 @@ def test_invoke_model_with_content_different_events( choice_content = [{"type": "text", "text": "This is a test"}] else: pytest.xfail("llm_model_value not handled: {llm_model_value}") - return body = get_invoke_model_body( llm_model_value, @@ -2070,7 +2068,6 @@ def test_invoke_model_with_content_tool_call( llm_model_config = AnthropicClaudeModel else: pytest.xfail("model family not handled: {model_family}") - return invoke_model_tool_call( span_exporter, @@ -2156,7 +2153,6 @@ def test_invoke_model_no_content( finish_reason = "length" else: pytest.xfail("model family not handled: {model_family}") - return choice_body = { "index": 0, @@ -2190,7 +2186,6 @@ def test_invoke_model_no_content_different_events( finish_reason = "end_turn" else: pytest.xfail("llm_model_value not handled: {llm_model_value}") - return body = get_invoke_model_body( llm_model_value, @@ -2246,7 +2241,6 @@ def test_invoke_model_no_content_tool_call( llm_model_config = AnthropicClaudeModel else: pytest.xfail("model family not handled: {model_family}") - return invoke_model_tool_call( span_exporter, @@ -2401,7 +2395,6 @@ def test_invoke_model_with_response_stream_with_content( } else: pytest.xfail("model family not handled: {model_family}") - return choice_body = { "index": 0, @@ -2437,7 +2430,6 @@ def test_invoke_model_with_response_stream_with_content_different_events( choice_content = [{"text": "This is a test", "type": "text"}] else: pytest.xfail("llm_model_value not handled: {llm_model_value}") - return max_tokens = 10 body = get_invoke_model_body( @@ -2672,7 +2664,6 @@ def test_invoke_model_with_response_stream_with_content_tool_call( llm_model_config = AnthropicClaudeModel else: pytest.xfail("model family not handled: {model_family}") - return invoke_model_with_response_stream_tool_call( span_exporter, @@ -2801,7 +2792,6 @@ def test_invoke_model_with_response_stream_no_content_different_events( finish_reason = "end_turn" else: pytest.xfail("llm_model_value not handled: {llm_model_value}") - return max_tokens = 10 body = get_invoke_model_body( @@ -2864,7 +2854,6 @@ def test_invoke_model_with_response_stream_no_content_tool_call( llm_model_config = AnthropicClaudeModel else: pytest.xfail("model family not handled: {model_family}") - return invoke_model_with_response_stream_tool_call( span_exporter, diff --git a/instrumentation/opentelemetry-instrumentation-threading/tests/test_threading.py b/instrumentation/opentelemetry-instrumentation-threading/tests/test_threading.py index 3a06969b26c..e0f1c63fbbf 100644 --- a/instrumentation/opentelemetry-instrumentation-threading/tests/test_threading.py +++ b/instrumentation/opentelemetry-instrumentation-threading/tests/test_threading.py @@ -15,7 +15,7 @@ from __future__ import annotations import threading -from concurrent.futures import ( # pylint: disable=no-name-in-module; TODO #4199 +from concurrent.futures import ( Future, ThreadPoolExecutor, ) diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index 5c833a4720b..0c92b6b6b80 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -424,7 +424,7 @@ def _get_span_name(method: str) -> str: return method -# pylint: disable=too-many-locals +# pylint: disable=too-many-locals,too-many-positional-arguments def _instrument( tracer: Tracer, duration_histogram_old: Histogram, diff --git a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py index 7e09e591e05..d28cc1e68d6 100644 --- a/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py +++ b/processor/opentelemetry-processor-baggage/src/opentelemetry/processor/baggage/processor.py @@ -23,7 +23,7 @@ BaggageKeyPredicateT = Callable[[str], bool] # A BaggageKeyPredicate that always returns True, allowing all baggage keys to be added to spans -ALLOW_ALL_BAGGAGE_KEYS: BaggageKeyPredicateT = lambda _: True # noqa: E731 +ALLOW_ALL_BAGGAGE_KEYS: BaggageKeyPredicateT = lambda _: True # noqa: E731 # pylint:disable=invalid-name class BaggageSpanProcessor(SpanProcessor): diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/sampler/_sampling_rule.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/sampler/_sampling_rule.py index fd99b2a87f9..0ee531017ef 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/sampler/_sampling_rule.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/sampler/_sampling_rule.py @@ -20,7 +20,7 @@ # Disable snake_case naming style so this class can match the sampling rules response from X-Ray -# pylint: disable=invalid-name +# pylint: disable=invalid-name,too-many-positional-arguments class _SamplingRule: def __init__( self, diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py index 79ebd3a1708..f2b9254f493 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py @@ -22,7 +22,7 @@ import posixpath import threading from collections import OrderedDict -from concurrent.futures import ( # pylint: disable=no-name-in-module; TODO #4199 +from concurrent.futures import ( Future, ThreadPoolExecutor, ) From 6783a42c2b0939760d91fbca56e76aa4ecd4d686 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 15 Apr 2026 01:12:55 -0700 Subject: [PATCH 74/78] feat(util-genai): refactor and make API smaller and more user-friendly (#4391) * Refactor public API on GenAI utils * more lint * review feedback * update tests to use named params * address some of the comments * up * fix failing checks and clean up imports * lint * lint * fix lint * replace @deprecated with docstring info to avoid warnings for users * up * common code for context manager --- .gitignore | 5 + instrumentation-genai/AGENTS.md | 41 ++ instrumentation-genai/CLAUDE.md | 1 + .../instrumentation/anthropic/patch.py | 5 +- .../instrumentation/anthropic/wrappers.py | 2 +- .../langchain/callback_handler.py | 10 +- .../pyproject.toml | 6 +- .../tests/requirements.latest.txt | 1 + .../tests/requirements.oldest.txt | 7 +- .../pyproject.toml | 2 +- .../instrumentation/openai_v2/patch.py | 2 +- .../openai_v2/response_wrappers.py | 5 +- .../instrumentation/openai_v2/utils.py | 2 +- util/opentelemetry-util-genai/AGENTS.md | 80 ++++ util/opentelemetry-util-genai/CHANGELOG.md | 7 +- util/opentelemetry-util-genai/CLAUDE.md | 1 + util/opentelemetry-util-genai/pyproject.toml | 1 + .../util/genai/_embedding_invocation.py | 124 +++++ .../util/genai/_inference_invocation.py | 358 +++++++++++++++ .../opentelemetry/util/genai/_invocation.py | 140 ++++++ .../util/genai/_tool_invocation.py | 96 ++++ .../util/genai/_workflow_invocation.py | 115 +++++ .../src/opentelemetry/util/genai/handler.py | 431 ++++++++---------- .../opentelemetry/util/genai/invocation.py | 47 ++ .../src/opentelemetry/util/genai/metrics.py | 116 +---- .../opentelemetry/util/genai/span_utils.py | 417 ----------------- .../src/opentelemetry/util/genai/types.py | 231 ++-------- .../tests/test_handler_metrics.py | 36 +- .../tests/test_handler_workflow.py | 177 ++----- .../tests/test_toolcall.py | 42 +- .../tests/test_utils.py | 249 +++++----- .../tests/test_utils_events.py | 108 ++--- .../tests/test_workflow_invocation.py | 75 ++- 33 files changed, 1579 insertions(+), 1361 deletions(-) create mode 100644 instrumentation-genai/AGENTS.md create mode 120000 instrumentation-genai/CLAUDE.md create mode 100644 util/opentelemetry-util-genai/AGENTS.md create mode 120000 util/opentelemetry-util-genai/CLAUDE.md create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/_workflow_invocation.py create mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/invocation.py delete mode 100644 util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py diff --git a/.gitignore b/.gitignore index 1c32b4446a9..6c3e08c1176 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,8 @@ target # Benchmark result files *-benchmark.json + +# opentelemetry-admin jobs +opentelemetry-admin-jobs.txt + +.claude/settings.local.json diff --git a/instrumentation-genai/AGENTS.md b/instrumentation-genai/AGENTS.md new file mode 100644 index 00000000000..6e8dd1eca90 --- /dev/null +++ b/instrumentation-genai/AGENTS.md @@ -0,0 +1,41 @@ +# GenAI Instrumentation — Agent and Contributor Guidelines + +Instrumentation packages here wrap specific libraries (OpenAI, Anthropic, etc.) and bridge +them to the shared telemetry layer in `util/opentelemetry-util-genai`. + +## 1. Instrumentation Layer Boundary + +Do not call OpenTelemetry APIs (`tracer`, `meter`, `span`, event APIs) directly. +Always go through `TelemetryHandler` and the invocation objects it returns. + +This layer is responsible only for: + +- Patching the library +- Parsing library-specific input/output into invocation fields + +Everything else (span creation, metric recording, event emission, context propagation) +belongs in `util/opentelemetry-util-genai`. + +## 2. Invocation Pattern + +Use `start_*()` and control span lifetime manually: + +```python +invocation = handler.start_inference(provider, request_model, server_address=..., server_port=...) +invocation.temperature = ... +try: + response = client.call(...) + invocation.response_model_name = response.model + invocation.finish_reasons = response.finish_reasons + invocation.stop() +except Exception as exc: + invocation.fail(exc) + raise +``` + +## 3. Exception Handling + +- Do not add `raise {Error}` statements in instrumentation/telemetry code — validation belongs in + tests and callers, not in the instrumentation layer. +- When catching exceptions from the underlying library to record telemetry, always re-raise + the original exception unmodified. diff --git a/instrumentation-genai/CLAUDE.md b/instrumentation-genai/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/instrumentation-genai/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py index 4dc8b55d388..845e10de3f9 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/patch.py @@ -26,7 +26,10 @@ gen_ai_attributes as GenAIAttributes, ) from opentelemetry.util.genai.handler import TelemetryHandler -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import ( + Error, + LLMInvocation, # TODO: migrate to InferenceInvocation +) from opentelemetry.util.genai.utils import ( should_capture_content_on_spans_in_experimental_mode, ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py index 52e2e68582b..1a9d5319a5b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-anthropic/src/opentelemetry/instrumentation/anthropic/wrappers.py @@ -31,7 +31,7 @@ from opentelemetry.util.genai.handler import TelemetryHandler from opentelemetry.util.genai.types import ( Error, - LLMInvocation, + LLMInvocation, # TODO: migrate to InferenceInvocation ) from .messages_extractors import set_invocation_response_attributes diff --git a/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py b/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py index d694857da44..5235af3c7f1 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py +++ b/instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py @@ -28,7 +28,7 @@ from opentelemetry.util.genai.types import ( Error, InputMessage, - LLMInvocation, + LLMInvocation, # TODO: migrate to InferenceInvocation MessagePart, OutputMessage, Text, @@ -158,7 +158,7 @@ def on_chat_model_start( self._invocation_manager.add_invocation_state( run_id=run_id, parent_run_id=parent_run_id, - invocation=llm_invocation, + invocation=llm_invocation, # pyright: ignore[reportArgumentType] ) def on_llm_end( @@ -171,7 +171,8 @@ def on_llm_end( ) -> None: llm_invocation = self._invocation_manager.get_invocation(run_id=run_id) if llm_invocation is None or not isinstance( - llm_invocation, LLMInvocation + llm_invocation, + LLMInvocation, ): # If the invocation does not exist, we cannot set attributes or end it return @@ -262,7 +263,8 @@ def on_llm_error( ) -> None: llm_invocation = self._invocation_manager.get_invocation(run_id=run_id) if llm_invocation is None or not isinstance( - llm_invocation, LLMInvocation + llm_invocation, + LLMInvocation, ): # If the invocation does not exist, we cannot set attributes or end it return diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml index e87c28d879a..fe7bfa6d82d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml @@ -25,10 +25,10 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "opentelemetry-api >= 1.37", + "opentelemetry-api >= 1.39", "opentelemetry-instrumentation >= 0.58b0", - "opentelemetry-semantic-conventions >= 0.58b0", - "opentelemetry-util-genai" + "opentelemetry-semantic-conventions >= 0.60b0", + "opentelemetry-util-genai >= 0.4b0.dev" ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.latest.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.latest.txt index e224e4349b6..2bd34ba349f 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.latest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.latest.txt @@ -50,4 +50,5 @@ grpcio>=1.60.0; implementation_name != "pypy" grpcio<1.60.0; implementation_name == "pypy" -e opentelemetry-instrumentation +-e util/opentelemetry-util-genai -e instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt index 2e935a63b6a..537c2b9ba22 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/requirements.oldest.txt @@ -26,10 +26,11 @@ pytest-asyncio==0.21.0 wrapt==1.16.0 opentelemetry-exporter-otlp-proto-grpc~=1.30 opentelemetry-exporter-otlp-proto-http~=1.30 -opentelemetry-api==1.37 # when updating, also update in pyproject.toml -opentelemetry-sdk==1.37 # when updating, also update in pyproject.toml -opentelemetry-semantic-conventions==0.58b0 # when updating, also update in pyproject.toml +opentelemetry-api==1.39 # when updating, also update in pyproject.toml +opentelemetry-sdk==1.39 # when updating, also update in pyproject.toml +opentelemetry-semantic-conventions==0.60b0 # when updating, also update in pyproject.toml grpcio>=1.60.0; implementation_name != "pypy" grpcio<1.60.0; implementation_name == "pypy" +-e util/opentelemetry-util-genai -e instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index 807d5bf9981..73bf8d3c57a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "opentelemetry-api ~= 1.39", "opentelemetry-instrumentation ~= 0.60b0", "opentelemetry-semantic-conventions ~= 0.60b0", - "opentelemetry-util-genai", + "opentelemetry-util-genai >= 0.4b0.dev", ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index 996c91c04df..30f74cfab11 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -36,7 +36,7 @@ from opentelemetry.util.genai.types import ( ContentCapturingMode, Error, - LLMInvocation, + LLMInvocation, # pylint: disable=no-name-in-module # TODO: migrate to InferenceInvocation OutputMessage, Text, ToolCallRequest, diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py index ce3375b8d5f..402e5c84c24 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_wrappers.py @@ -8,7 +8,10 @@ from typing import TYPE_CHECKING, Callable, Generator, Generic, TypeVar from opentelemetry.util.genai.handler import TelemetryHandler -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import ( + Error, + LLMInvocation, # pylint: disable=no-name-in-module # TODO: migrate to InferenceInvocation +) # OpenAI Responses internals are version-gated (added in openai>=1.66.0), so # pylint may not resolve them in all lint environments even though we guard diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index 6afca130b6e..bd566ddba53 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -38,7 +38,7 @@ from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.genai.types import ( InputMessage, - LLMInvocation, + LLMInvocation, # pylint: disable=no-name-in-module # TODO: migrate to InferenceInvocation OutputMessage, Text, ToolCallRequest, diff --git a/util/opentelemetry-util-genai/AGENTS.md b/util/opentelemetry-util-genai/AGENTS.md new file mode 100644 index 00000000000..355d8b7c082 --- /dev/null +++ b/util/opentelemetry-util-genai/AGENTS.md @@ -0,0 +1,80 @@ +# GenAI Utils — Agent and Contributor Guidelines + +This package provides shared telemetry utilities for OpenTelemetry GenAI instrumentation. + +## 1. Semantic Convention Compliance + +All attributes, operation names, and span names must match the +[OpenTelemetry GenAI semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/) +exactly. + +Use the appropriate semconv attribute modules — do not hardcode attribute name strings: + +- `gen_ai.*` attributes: `opentelemetry.semconv._incubating.attributes.gen_ai_attributes` +- `server.*` attributes: `opentelemetry.semconv.attributes.server_attributes` +- `error.*` attributes: `opentelemetry.semconv.attributes.error_attributes` +- Other namespaces: use the corresponding module from `opentelemetry.semconv` + +## 2. Invocation Lifecycle Pattern + +Every new operation type must follow this pattern: + +```python +invocation = handler.start_inference(provider, request_model, server_address=..., server_port=...) +invocation.temperature = ... +try: + response = client.call(...) + invocation.response_model_name = response.model + invocation.finish_reasons = response.finish_reasons + invocation.stop() +except Exception as exc: + invocation.fail(exc) + raise +``` + +Factory methods on `TelemetryHandler` (`handler.py`): + +- `start_inference(provider, request_model, *, server_address, server_port)` → `InferenceInvocation` +- `start_embedding(provider, request_model, *, server_address, server_port)` → `EmbeddingInvocation` +- `start_tool(name, *, arguments, tool_call_id, tool_type, tool_description)` → `ToolInvocation` +- `start_workflow(name)` → `WorkflowInvocation` + +Context manager equivalents (`handler.inference()`, `handler.embedding()`, `handler.tool()`, +`handler.workflow()`) are available when the span lifetime maps cleanly to a `with` block. + +### Anti-patterns + +**Never construct invocation types directly** (`InferenceInvocation(...)`, `ToolInvocation(...)`, +etc.) in instrumentation or production code — direct construction skips span creation and context +propagation, so all telemetry calls become no-ops. Always use `handler.start_*()`. + +## 3. Exception Handling + +- Do not add `raise {Error}` statements to `handler.py` or `types.py` — validation belongs in + tests and callers, not telemetry internals. +- When catching exceptions from the underlying library to record telemetry, always re-raise + the original exception unmodified. + +## 4. Documentation + +- Docstrings for invocation types and span/event helpers must include a link to the + corresponding operation in the semconv spec. +- When adding or changing attributes, update the docstring to describe what is set and under + what conditions (e.g., "set only when `server_address` is provided"). + +## 5. Tests + +- Every new operation type or attribute change must have tests verifying the exact attribute + names and values produced, checked against the semconv spec. +- Cover all paths: success (`invocation.stop()`), failure (`invocation.fail(exc)`), and any + conditional attribute logic (e.g., attributes set only when optional fields are populated). +- Tests live in `tests/` — follow existing patterns there. +- Don't call internal API in tests when the public API is available. + +## 6. Python API Conventions + +- Mark private modules with an underscore. +- Objects inside of a private module should be prefixed with underscopre if they + are not used outside the that module. +- Before removing or renaming an object exposed publicly, deprecate it first with + `@deprecated("... Use X instead.")` pointing to the replacement; diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index c4d57c28b68..3b8f0b1d8cc 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -9,11 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add metrics support for EmbeddingInvocation ([#4377](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4377)) -- Add metrics support for EmbeddingInvocation - ([#5022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/5022)) - Add support for workflow in genAI utils handler. ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4366](#4366)) -- Enrich ToolCall type, breaking change: usage of ToolCall class renamed to ToolCallRequest +- Enrich ToolCall type, breaking change: usage of ToolCall class renamed to ToolCallRequest ([#4218](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4218)) - Add EmbeddingInvocation span lifecycle support ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4219](#4219)) @@ -23,6 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4310](#4310)) - Check if upload works at startup in initializer of the `UploadCompletionHook`, instead of repeatedly failing on every upload ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4390](#4390)). +- Refactor public API: add factory methods (`start_inference`, `start_embedding`, `start_tool`, `start_workflow`) and invocation-owned lifecycle (`invocation.stop()` / `invocation.fail(exc)`); rename `LLMInvocation` → `InferenceInvocation` and `ToolCall` → `ToolInvocation`. Existing usages remain fully functional via deprecated aliases. + ([#4391](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4391)) + ## Version 0.3b0 (2026-02-20) diff --git a/util/opentelemetry-util-genai/CLAUDE.md b/util/opentelemetry-util-genai/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/util/opentelemetry-util-genai/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/util/opentelemetry-util-genai/pyproject.toml b/util/opentelemetry-util-genai/pyproject.toml index be3ba572385..3e95fb30391 100644 --- a/util/opentelemetry-util-genai/pyproject.toml +++ b/util/opentelemetry-util-genai/pyproject.toml @@ -49,3 +49,4 @@ include = ["/src", "/tests"] [tool.hatch.build.targets.wheel] packages = ["src/opentelemetry"] + diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py new file mode 100644 index 00000000000..e7fa59b6000 --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py @@ -0,0 +1,124 @@ +# 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 __future__ import annotations + +from typing import Any + +from opentelemetry._logs import Logger +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.semconv.attributes import server_attributes +from opentelemetry.trace import SpanKind, Tracer +from opentelemetry.util.genai._invocation import Error, GenAIInvocation +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder +from opentelemetry.util.types import AttributeValue + + +class EmbeddingInvocation(GenAIInvocation): + """Represents a single embedding model invocation. + + Use handler.start_embedding(provider) or the handler.embedding(provider) + context manager rather than constructing this directly. + """ + + def __init__( + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + provider: str, + *, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + encoding_formats: list[str] | None = None, + input_tokens: int | None = None, + dimension_count: int | None = None, + response_model_name: str | None = None, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + """Use handler.start_embedding(provider) or handler.embedding(provider) instead of calling this directly.""" + _operation_name = GenAI.GenAiOperationNameValues.EMBEDDINGS.value + super().__init__( + tracer, + metrics_recorder, + logger, + operation_name=_operation_name, + span_name=f"{_operation_name} {request_model}" + if request_model + else _operation_name, + span_kind=SpanKind.CLIENT, + attributes=attributes, + metric_attributes=metric_attributes, + ) + self.provider = provider # e.g., azure.ai.openai, openai, aws.bedrock + self.request_model = request_model + self.server_address = server_address + self.server_port = server_port + # encoding_formats can be multi-value -> combinational cardinality risk. + # Keep on spans/events only. + self.encoding_formats = encoding_formats + self.input_tokens = input_tokens + self.dimension_count = dimension_count + self.response_model_name = response_model_name + self._start() + + def _get_metric_attributes(self) -> dict[str, Any]: + optional_attrs = ( + (GenAI.GEN_AI_PROVIDER_NAME, self.provider), + (GenAI.GEN_AI_REQUEST_MODEL, self.request_model), + (GenAI.GEN_AI_RESPONSE_MODEL, self.response_model_name), + (server_attributes.SERVER_ADDRESS, self.server_address), + (server_attributes.SERVER_PORT, self.server_port), + ) + attrs: dict[str, AttributeValue] = { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name, + **{k: v for k, v in optional_attrs if v is not None}, + } + attrs.update(self.metric_attributes) + return attrs + + def _get_metric_token_counts(self) -> dict[str, int]: + if self.input_tokens is not None: + return {GenAI.GenAiTokenTypeValues.INPUT.value: self.input_tokens} + return {} + + def _apply_finish(self, error: Error | None = None) -> None: + optional_attrs = ( + (GenAI.GEN_AI_PROVIDER_NAME, self.provider), + (server_attributes.SERVER_ADDRESS, self.server_address), + (server_attributes.SERVER_PORT, self.server_port), + (GenAI.GEN_AI_REQUEST_MODEL, self.request_model), + (GenAI.GEN_AI_EMBEDDINGS_DIMENSION_COUNT, self.dimension_count), + (GenAI.GEN_AI_REQUEST_ENCODING_FORMATS, self.encoding_formats), + (GenAI.GEN_AI_RESPONSE_MODEL, self.response_model_name), + (GenAI.GEN_AI_USAGE_INPUT_TOKENS, self.input_tokens), + ) + attributes: dict[str, Any] = { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name, + **{ + key: value + for key, value in optional_attrs + if value is not None + }, + } + if error is not None: + self._apply_error_attributes(error) + attributes.update(self.attributes) + self.span.set_attributes(attributes) + # Metrics recorder currently supports InferenceInvocation fields only. + # No-op until dedicated embedding metric support is added. diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py new file mode 100644 index 00000000000..a1bd55811c9 --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_inference_invocation.py @@ -0,0 +1,358 @@ +# 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 __future__ import annotations + +from dataclasses import asdict, dataclass, field +from typing import Any + +from opentelemetry._logs import Logger, LogRecord +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.semconv.attributes import server_attributes +from opentelemetry.trace import INVALID_SPAN, Span, SpanKind, Tracer +from opentelemetry.util.genai._invocation import Error, GenAIInvocation +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder +from opentelemetry.util.genai.types import ( + InputMessage, + MessagePart, + OutputMessage, +) +from opentelemetry.util.genai.utils import ( + ContentCapturingMode, + gen_ai_json_dumps, + get_content_capturing_mode, + is_experimental_mode, + should_emit_event, +) + + +class InferenceInvocation(GenAIInvocation): + """Represents a single LLM chat/completion call. + + Use handler.start_inference(provider) or the handler.inference(provider) + context manager rather than constructing this directly. + """ + + def __init__( # pylint: disable=too-many-locals + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + provider: str, + *, + request_model: str | None = None, + input_messages: list[InputMessage] | None = None, + output_messages: list[OutputMessage] | None = None, + system_instruction: list[MessagePart] | None = None, + response_model_name: str | None = None, + response_id: str | None = None, + finish_reasons: list[str] | None = None, + input_tokens: int | None = None, + output_tokens: int | None = None, + temperature: float | None = None, + top_p: float | None = None, + frequency_penalty: float | None = None, + presence_penalty: float | None = None, + max_tokens: int | None = None, + stop_sequences: list[str] | None = None, + seed: int | None = None, + server_address: str | None = None, + server_port: int | None = None, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + """Use handler.start_inference(provider) or handler.inference(provider) instead of calling this directly.""" + _operation_name = GenAI.GenAiOperationNameValues.CHAT.value + super().__init__( + tracer, + metrics_recorder, + logger, + operation_name=_operation_name, + span_name=f"{_operation_name} {request_model}" + if request_model + else _operation_name, + span_kind=SpanKind.CLIENT, + attributes=attributes, + metric_attributes=metric_attributes, + ) + self.provider = provider + self.request_model = request_model + self.input_messages: list[InputMessage] = ( + [] if input_messages is None else input_messages + ) + self.output_messages: list[OutputMessage] = ( + [] if output_messages is None else output_messages + ) + self.system_instruction: list[MessagePart] = ( + [] if system_instruction is None else system_instruction + ) + self.response_model_name = response_model_name + self.response_id = response_id + self.finish_reasons = finish_reasons + self.input_tokens = input_tokens + self.output_tokens = output_tokens + self.temperature = temperature + self.top_p = top_p + self.frequency_penalty = frequency_penalty + self.presence_penalty = presence_penalty + self.max_tokens = max_tokens + self.stop_sequences = stop_sequences + self.seed = seed + self.server_address = server_address + self.server_port = server_port + self._start() + + def _get_message_attributes(self, *, for_span: bool) -> dict[str, Any]: + if not is_experimental_mode(): + return {} + mode = get_content_capturing_mode() + allowed_modes = ( + ( + ContentCapturingMode.SPAN_ONLY, + ContentCapturingMode.SPAN_AND_EVENT, + ) + if for_span + else ( + ContentCapturingMode.EVENT_ONLY, + ContentCapturingMode.SPAN_AND_EVENT, + ) + ) + if mode not in allowed_modes: + return {} + + def serialize(items: list[Any]) -> Any: + dicts = [asdict(item) for item in items] + return gen_ai_json_dumps(dicts) if for_span else dicts + + optional_attrs = ( + ( + GenAI.GEN_AI_INPUT_MESSAGES, + serialize(self.input_messages) + if self.input_messages + else None, + ), + ( + GenAI.GEN_AI_OUTPUT_MESSAGES, + serialize(self.output_messages) + if self.output_messages + else None, + ), + ( + GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, + serialize(self.system_instruction) + if self.system_instruction + else None, + ), + ) + return { + key: value for key, value in optional_attrs if value is not None + } + + def _get_finish_reasons(self) -> list[str] | None: + if self.finish_reasons is not None: + return self.finish_reasons or None + if self.output_messages: + reasons = [ + msg.finish_reason + for msg in self.output_messages + if msg.finish_reason + ] + return reasons or None + return None + + def _get_base_attributes(self) -> dict[str, Any]: + optional_attrs = ( + (GenAI.GEN_AI_REQUEST_MODEL, self.request_model), + (GenAI.GEN_AI_PROVIDER_NAME, self.provider), + (server_attributes.SERVER_ADDRESS, self.server_address), + (server_attributes.SERVER_PORT, self.server_port), + ) + return { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name, + **{k: v for k, v in optional_attrs if v is not None}, + } + + def _get_attributes(self) -> dict[str, Any]: + attrs = self._get_base_attributes() + optional_attrs = ( + (GenAI.GEN_AI_REQUEST_TEMPERATURE, self.temperature), + (GenAI.GEN_AI_REQUEST_TOP_P, self.top_p), + (GenAI.GEN_AI_REQUEST_FREQUENCY_PENALTY, self.frequency_penalty), + (GenAI.GEN_AI_REQUEST_PRESENCE_PENALTY, self.presence_penalty), + (GenAI.GEN_AI_REQUEST_MAX_TOKENS, self.max_tokens), + (GenAI.GEN_AI_REQUEST_STOP_SEQUENCES, self.stop_sequences), + (GenAI.GEN_AI_REQUEST_SEED, self.seed), + (GenAI.GEN_AI_RESPONSE_FINISH_REASONS, self._get_finish_reasons()), + (GenAI.GEN_AI_RESPONSE_MODEL, self.response_model_name), + (GenAI.GEN_AI_RESPONSE_ID, self.response_id), + (GenAI.GEN_AI_USAGE_INPUT_TOKENS, self.input_tokens), + (GenAI.GEN_AI_USAGE_OUTPUT_TOKENS, self.output_tokens), + ) + attrs.update({k: v for k, v in optional_attrs if v is not None}) + return attrs + + def _get_metric_attributes(self) -> dict[str, Any]: + attrs = self._get_base_attributes() + if self.response_model_name is not None: + attrs[GenAI.GEN_AI_RESPONSE_MODEL] = self.response_model_name + attrs.update(self.metric_attributes) + return attrs + + def _get_metric_token_counts(self) -> dict[str, int]: + counts: dict[str, int] = {} + if self.input_tokens is not None: + counts[GenAI.GenAiTokenTypeValues.INPUT.value] = self.input_tokens + if self.output_tokens is not None: + counts[GenAI.GenAiTokenTypeValues.OUTPUT.value] = ( + self.output_tokens + ) + return counts + + def _apply_finish(self, error: Error | None = None) -> None: + if error is not None: + self._apply_error_attributes(error) + attributes = self._get_attributes() + attributes.update(self._get_message_attributes(for_span=True)) + attributes.update(self.attributes) + self.span.set_attributes(attributes) + self._metrics_recorder.record(self) + self._emit_event() + + def _emit_event(self) -> None: + """Emit a gen_ai.client.inference.operation.details event. + + For more details, see the semantic convention documentation: + https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md#event-eventgen_aiclientinferenceoperationdetails + """ + if not is_experimental_mode() or not should_emit_event(): + return + + attributes = self._get_attributes() + attributes.update(self._get_message_attributes(for_span=False)) + attributes.update(self.attributes) + self._logger.emit( + LogRecord( + event_name="gen_ai.client.inference.operation.details", + attributes=attributes, + context=self._span_context, + ) + ) + + +@dataclass +class LLMInvocation: + """Deprecated. Use InferenceInvocation instead. + + Data container for an LLM invocation. Pass to handler.start_llm() to start + the span, then update fields and call handler.stop_llm() or handler.fail_llm(). + """ + + request_model: str | None = None + input_messages: list[InputMessage] = field(default_factory=list) # pyright: ignore[reportUnknownVariableType] + output_messages: list[OutputMessage] = field(default_factory=list) # pyright: ignore[reportUnknownVariableType] + system_instruction: list[MessagePart] = field(default_factory=list) # pyright: ignore[reportUnknownVariableType] + provider: str | None = None + response_model_name: str | None = None + response_id: str | None = None + finish_reasons: list[str] | None = None + input_tokens: int | None = None + output_tokens: int | None = None + attributes: dict[str, Any] = field(default_factory=dict) # pyright: ignore[reportUnknownVariableType] + """Additional attributes to set on spans and/or events. Not set on metrics.""" + metric_attributes: dict[str, Any] = field(default_factory=dict) # pyright: ignore[reportUnknownVariableType] + """Additional attributes to set on metrics. Must be low cardinality. Not set on spans or events.""" + temperature: float | None = None + top_p: float | None = None + frequency_penalty: float | None = None + presence_penalty: float | None = None + max_tokens: int | None = None + stop_sequences: list[str] | None = None + seed: int | None = None + server_address: str | None = None + server_port: int | None = None + + _inference_invocation: InferenceInvocation | None = field( + default=None, init=False, repr=False + ) + + def _start_with_handler( + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + ) -> None: + """Create and start an InferenceInvocation from this data container. Called by handler.start_llm().""" + self._inference_invocation = InferenceInvocation( + tracer, + metrics_recorder, + logger, + self.provider or "", + request_model=self.request_model, + input_messages=self.input_messages, + output_messages=self.output_messages, + system_instruction=self.system_instruction, + response_model_name=self.response_model_name, + response_id=self.response_id, + finish_reasons=self.finish_reasons, + input_tokens=self.input_tokens, + output_tokens=self.output_tokens, + temperature=self.temperature, + top_p=self.top_p, + frequency_penalty=self.frequency_penalty, + presence_penalty=self.presence_penalty, + max_tokens=self.max_tokens, + stop_sequences=self.stop_sequences, + seed=self.seed, + server_address=self.server_address, + server_port=self.server_port, + attributes=self.attributes, + metric_attributes=self.metric_attributes, + ) + + def _sync_to_invocation(self) -> None: + inv = self._inference_invocation + if inv is None: + return + inv.provider = self.provider or "" + inv.request_model = self.request_model + inv.input_messages = self.input_messages + inv.output_messages = self.output_messages + inv.system_instruction = self.system_instruction + inv.response_model_name = self.response_model_name + inv.response_id = self.response_id + inv.finish_reasons = self.finish_reasons + inv.input_tokens = self.input_tokens + inv.output_tokens = self.output_tokens + inv.temperature = self.temperature + inv.top_p = self.top_p + inv.frequency_penalty = self.frequency_penalty + inv.presence_penalty = self.presence_penalty + inv.max_tokens = self.max_tokens + inv.stop_sequences = self.stop_sequences + inv.seed = self.seed + inv.server_address = self.server_address + inv.server_port = self.server_port + inv.attributes = self.attributes + inv.metric_attributes = self.metric_attributes + + @property + def span(self) -> Span: + """The underlying span, for back-compat with code that checks span.is_recording().""" + return ( + self._inference_invocation.span + if self._inference_invocation is not None + else INVALID_SPAN + ) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_invocation.py new file mode 100644 index 00000000000..b63d9a32b4f --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_invocation.py @@ -0,0 +1,140 @@ +# 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 __future__ import annotations + +import timeit +from abc import ABC, abstractmethod +from contextlib import contextmanager +from contextvars import Token +from typing import TYPE_CHECKING, Any, Iterator + +from typing_extensions import Self, TypeAlias + +from opentelemetry._logs import Logger +from opentelemetry.context import Context, attach, detach +from opentelemetry.semconv.attributes import error_attributes +from opentelemetry.trace import INVALID_SPAN as _INVALID_SPAN +from opentelemetry.trace import Span, SpanKind, Tracer, set_span_in_context +from opentelemetry.trace.status import Status, StatusCode +from opentelemetry.util.genai.types import Error + +if TYPE_CHECKING: + from opentelemetry.util.genai.metrics import InvocationMetricsRecorder + +ContextToken: TypeAlias = Token[Context] + + +class GenAIInvocation(ABC): + """ + Base class for all GenAI invocation types. Manages the lifecycle of a single + GenAI operation (LLM call, embedding, tool execution, workflow, etc.). + + Use the factory methods on TelemetryHandler (start_inference, start_embedding, + start_workflow, start_tool) rather than constructing invocations directly. + """ + + def __init__( + self, + # Individual components instead of TelemetryHandler to avoid a circular + # import between handler.py and the invocation modules. + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + operation_name: str, + span_name: str, + span_kind: SpanKind = SpanKind.CLIENT, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + self._tracer = tracer + self._metrics_recorder = metrics_recorder + self._logger = logger + self._operation_name: str = operation_name + self.attributes: dict[str, Any] = ( + {} if attributes is None else attributes + ) + """Additional attributes to set on spans and/or events. Not set on metrics.""" + self.metric_attributes: dict[str, Any] = ( + {} if metric_attributes is None else metric_attributes + ) + """Additional attributes to set on metrics. Must be low cardinality. Not set on spans or events.""" + self.span: Span = _INVALID_SPAN + self._span_context: Context + self._span_name: str = span_name + self._span_kind: SpanKind = span_kind + self._context_token: ContextToken | None = None + self._monotonic_start_s: float | None = None + + def _start(self) -> None: + """Start the invocation span and attach it to the current context.""" + self.span = self._tracer.start_span( + name=self._span_name, + kind=self._span_kind, + ) + self._span_context = set_span_in_context(self.span) + self._monotonic_start_s = timeit.default_timer() + self._context_token = attach(self._span_context) + + def _get_metric_attributes(self) -> dict[str, Any]: + """Return low-cardinality attributes for metric recording.""" + return self.metric_attributes + + def _get_metric_token_counts(self) -> dict[str, int]: # pylint: disable=no-self-use + """Return {token_type: count} for token histogram recording.""" + return {} + + def _apply_error_attributes(self, error: Error) -> None: + """Apply error status and error.type attribute to the span, events, and metrics.""" + error_type = error.type.__qualname__ + self.span.set_status(Status(StatusCode.ERROR, error.message)) + self.attributes[error_attributes.ERROR_TYPE] = error_type + self.metric_attributes[error_attributes.ERROR_TYPE] = error_type + + @abstractmethod + def _apply_finish(self, error: Error | None = None) -> None: + """Apply finish telemetry (attributes, metrics, events).""" + + def _finish(self, error: Error | None = None) -> None: + """Apply finish telemetry and end the span.""" + if self._context_token is None: + return + try: + self._apply_finish(error) + finally: + try: + detach(self._context_token) + except Exception: # pylint: disable=broad-except + pass + self.span.end() + + def stop(self) -> None: + """Finalize the invocation successfully and end its span.""" + self._finish() + + def fail(self, error: Error | BaseException) -> None: + """Fail the invocation and end its span with error status.""" + if isinstance(error, BaseException): + error = Error(type=type(error), message=str(error)) + self._finish(error) + + @contextmanager + def _managed(self) -> Iterator[Self]: + """Context manager that calls stop() on success or fail() on exception.""" + try: + yield self + except Exception as exc: + self.fail(exc) + raise + self.stop() diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py new file mode 100644 index 00000000000..1ebbd85bc69 --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_tool_invocation.py @@ -0,0 +1,96 @@ +# 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 __future__ import annotations + +from typing import Any + +from opentelemetry._logs import Logger +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.trace import Tracer +from opentelemetry.util.genai._invocation import Error, GenAIInvocation +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder + + +class ToolInvocation(GenAIInvocation): + """Represents a tool call invocation for execute_tool span tracking. + + Not used as a message part — use ToolCallRequest for that purpose. + + Use handler.start_tool(name) rather than constructing this directly. + + Reference: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md#execute-tool-span + + Semantic convention attributes for execute_tool spans: + - gen_ai.operation.name: "execute_tool" (Required) + - gen_ai.tool.name: Name of the tool (Recommended) + - gen_ai.tool.call.id: Tool call identifier (Recommended if available) + - gen_ai.tool.type: Type classification - "function", "extension", or "datastore" (Recommended if available) + - gen_ai.tool.description: Tool description (Recommended if available) + - gen_ai.tool.call.arguments: Parameters passed to tool (Opt-In, may contain sensitive data) + - gen_ai.tool.call.result: Result returned by tool (Opt-In, may contain sensitive data) + - error.type: Error type if operation failed (Conditionally Required) + """ + + def __init__( + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + name: str, + *, + arguments: Any = None, + tool_call_id: str | None = None, + tool_type: str | None = None, + tool_description: str | None = None, + tool_result: Any = None, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + """Use handler.start_tool(name) or handler.tool(name) instead of calling this directly.""" + _operation_name = GenAI.GenAiOperationNameValues.EXECUTE_TOOL.value + super().__init__( + tracer, + metrics_recorder, + logger, + operation_name=_operation_name, + span_name=f"{_operation_name} {name}" if name else _operation_name, + attributes=attributes, + metric_attributes=metric_attributes, + ) + self.name = name + self.arguments = arguments + self.tool_call_id = tool_call_id + self.tool_type = tool_type + self.tool_description = tool_description + self.tool_result = tool_result + self._start() + + def _apply_finish(self, error: Error | None = None) -> None: + if error is not None: + self._apply_error_attributes(error) + optional_attrs = ( + (GenAI.GEN_AI_TOOL_NAME, self.name), + (GenAI.GEN_AI_TOOL_CALL_ID, self.tool_call_id), + (GenAI.GEN_AI_TOOL_TYPE, self.tool_type), + (GenAI.GEN_AI_TOOL_DESCRIPTION, self.tool_description), + ) + attributes: dict[str, Any] = { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name, + **{k: v for k, v in optional_attrs if v is not None}, + } + attributes.update(self.attributes) + self.span.set_attributes(attributes) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_workflow_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_workflow_invocation.py new file mode 100644 index 00000000000..e3b45535d29 --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_workflow_invocation.py @@ -0,0 +1,115 @@ +# 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 __future__ import annotations + +from dataclasses import asdict +from typing import Any + +from opentelemetry._logs import Logger +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAI, +) +from opentelemetry.trace import SpanKind, Tracer +from opentelemetry.util.genai._invocation import Error, GenAIInvocation +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder +from opentelemetry.util.genai.types import ( + InputMessage, + OutputMessage, +) +from opentelemetry.util.genai.utils import ( + ContentCapturingMode, + gen_ai_json_dumps, + get_content_capturing_mode, + is_experimental_mode, +) + + +class WorkflowInvocation(GenAIInvocation): + """ + Represents a predetermined sequence of operations (e.g. agent, LLM, tool, + and retrieval invocations). A workflow groups multiple operations together, + accepting input(s) and producing final output(s). + + Use handler.start_workflow(name) or the handler.workflow(name) context + manager rather than constructing this directly. + """ + + def __init__( + self, + tracer: Tracer, + metrics_recorder: InvocationMetricsRecorder, + logger: Logger, + name: str | None, + *, + input_messages: list[InputMessage] | None = None, + output_messages: list[OutputMessage] | None = None, + attributes: dict[str, Any] | None = None, + metric_attributes: dict[str, Any] | None = None, + ) -> None: + """Use handler.start_workflow(name) or handler.workflow(name) instead of calling this directly.""" + _operation_name = "invoke_workflow" + super().__init__( + tracer, + metrics_recorder, + logger, + operation_name=_operation_name, + span_name=f"{_operation_name} {name}" if name else _operation_name, + span_kind=SpanKind.INTERNAL, + attributes=attributes, + metric_attributes=metric_attributes, + ) + self.name = name + self.input_messages: list[InputMessage] = ( + [] if input_messages is None else input_messages + ) + self.output_messages: list[OutputMessage] = ( + [] if output_messages is None else output_messages + ) + self._start() + + def _get_messages_for_span(self) -> dict[str, Any]: + if not is_experimental_mode() or get_content_capturing_mode() not in ( + ContentCapturingMode.SPAN_ONLY, + ContentCapturingMode.SPAN_AND_EVENT, + ): + return {} + optional_attrs = ( + ( + GenAI.GEN_AI_INPUT_MESSAGES, + gen_ai_json_dumps([asdict(m) for m in self.input_messages]) + if self.input_messages + else None, + ), + ( + GenAI.GEN_AI_OUTPUT_MESSAGES, + gen_ai_json_dumps([asdict(m) for m in self.output_messages]) + if self.output_messages + else None, + ), + ) + return { + key: value for key, value in optional_attrs if value is not None + } + + def _apply_finish(self, error: Error | None = None) -> None: + attributes: dict[str, Any] = { + GenAI.GEN_AI_OPERATION_NAME: self._operation_name + } + attributes.update(self._get_messages_for_span()) + if error is not None: + self._apply_error_attributes(error) + attributes.update(self.attributes) + self.span.set_attributes(attributes) + # TODO: Add workflow metrics when supported diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py index 8207af977c0..9ef4a5592d6 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py @@ -17,7 +17,6 @@ This module exposes the `TelemetryHandler` class, which manages the lifecycle of GenAI (Generative AI) invocations and emits telemetry data (spans and related attributes). -It supports starting, stopping, and failing LLM invocations. Classes: - TelemetryHandler: Manages GenAI invocation lifecycles and emits telemetry. @@ -28,44 +27,29 @@ Usage: handler = get_telemetry_handler() - # Create an invocation object with your request data - # The span and context_token attributes are set by the TelemetryHandler, and - # managed by the TelemetryHandler during the lifecycle of the span. - - # Use the context manager to manage the lifecycle of an LLM invocation. - with handler.llm(invocation) as invocation: - # Populate outputs and any additional attributes + # Factory method: construct and start in one call, then stop or fail. + invocation = handler.start_inference("my-provider", request_model="my-model") + invocation.input_messages = [...] + invocation.temperature = 0.7 + try: + # ... call the underlying library ... + invocation.output_messages = [...] + invocation.stop() + except Exception as exc: + invocation.fail(exc) + raise + + # Or use the context manager form — exception handling is automatic. + with handler.inference("my-provider", request_model="my-model") as invocation: + invocation.input_messages = [...] + # ... call the underlying library ... invocation.output_messages = [...] - invocation.attributes.update({"more": "attrs"}) - - # Or, if you prefer to manage the lifecycle manually - invocation = LLMInvocation( - request_model="my-model", - input_messages=[...], - provider="my-provider", - attributes={"custom": "attr"}, - ) - - # Start the invocation (opens a span) - handler.start_llm(invocation) - - # Populate outputs and any additional attributes, then stop (closes the span) - invocation.output_messages = [...] - invocation.attributes.update({"more": "attrs"}) - handler.stop_llm(invocation) - - # Or, in case of error - handler.fail_llm(invocation, Error(type="...", message="...")) """ from __future__ import annotations -import logging -import timeit -from contextlib import contextmanager -from typing import Iterator, TypeVar +from contextlib import AbstractContextManager -from opentelemetry import context as otel_context from opentelemetry._logs import ( LoggerProvider, get_logger, @@ -73,51 +57,22 @@ from opentelemetry.metrics import MeterProvider, get_meter from opentelemetry.semconv.schemas import Schemas from opentelemetry.trace import ( - Span, - SpanKind, TracerProvider, get_tracer, - set_span_in_context, ) -from opentelemetry.util.genai.metrics import InvocationMetricsRecorder -from opentelemetry.util.genai.span_utils import ( - _apply_embedding_finish_attributes, - _apply_error_attributes, - _apply_llm_finish_attributes, - _apply_workflow_finish_attributes, - _get_embedding_span_name, - _get_llm_span_name, - _get_workflow_span_name, - _maybe_emit_llm_event, +from opentelemetry.util.genai._inference_invocation import ( + LLMInvocation, ) -from opentelemetry.util.genai.types import ( +from opentelemetry.util.genai._invocation import Error +from opentelemetry.util.genai.invocation import ( EmbeddingInvocation, - Error, - GenAIInvocation, - LLMInvocation, + InferenceInvocation, + ToolInvocation, WorkflowInvocation, ) +from opentelemetry.util.genai.metrics import InvocationMetricsRecorder from opentelemetry.util.genai.version import __version__ -_logger = logging.getLogger(__name__) - - -def _safe_detach(invocation: GenAIInvocation) -> None: - """Detach the context token if still present, as a safety net.""" - if invocation.context_token is not None: - try: - otel_context.detach(invocation.context_token) - except Exception: # pylint: disable=broad-except - pass - if invocation.span is not None: - try: - invocation.span.end() - except Exception: # pylint: disable=broad-except - pass - - -_T = TypeVar("_T", bound=GenAIInvocation) - class TelemetryHandler: """ @@ -138,7 +93,6 @@ def __init__( tracer_provider, schema_url=schema_url, ) - self._metrics_recorder: InvocationMetricsRecorder | None = None meter = get_meter( __name__, meter_provider=meter_provider, schema_url=schema_url ) @@ -150,137 +104,139 @@ def __init__( schema_url=schema_url, ) - def _record_metrics( + # New-style factory methods: construct + start in one call, handler stored on invocation + + def start_inference( self, - invocation: GenAIInvocation, - span: Span | None = None, + provider: str, *, - error_type: str | None = None, - ) -> None: - if self._metrics_recorder is None or span is None: - return - self._metrics_recorder.record( - span, - invocation, - error_type=error_type, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + ) -> InferenceInvocation: + """Create and start an LLM inference invocation. + + Set remaining attributes (input_messages, temperature, etc.) on the + returned invocation, then call invocation.stop() or invocation.fail(). + """ + return InferenceInvocation( + self._tracer, + self._metrics_recorder, + self._logger, + provider, + request_model=request_model, + server_address=server_address, + server_port=server_port, ) - def _start(self, invocation: _T) -> _T: - """Start a GenAI invocation and create a pending span entry.""" - if isinstance(invocation, LLMInvocation): - span_name = _get_llm_span_name(invocation) - kind = SpanKind.CLIENT - elif isinstance(invocation, EmbeddingInvocation): - span_name = _get_embedding_span_name(invocation) - kind = SpanKind.CLIENT - elif isinstance(invocation, WorkflowInvocation): - span_name = _get_workflow_span_name(invocation) - kind = SpanKind.INTERNAL - else: - span_name = "" - kind = SpanKind.CLIENT - span = self._tracer.start_span( - name=span_name, - kind=kind, - ) - # Record a monotonic start timestamp (seconds) for duration - # calculation using timeit.default_timer. - invocation.monotonic_start_s = timeit.default_timer() - invocation.span = span - invocation.context_token = otel_context.attach( - set_span_in_context(span) - ) - return invocation + def start_llm(self, invocation: LLMInvocation) -> LLMInvocation: + """Start an LLM invocation. - def _stop(self, invocation: _T) -> _T: - """Finalize a GenAI invocation successfully and end its span.""" - if invocation.context_token is None or invocation.span is None: - # TODO: Provide feedback that this invocation was not started - return invocation - - span = invocation.span - try: - if isinstance(invocation, LLMInvocation): - _apply_llm_finish_attributes(span, invocation) - self._record_metrics(invocation, span) - _maybe_emit_llm_event(self._logger, span, invocation) - elif isinstance(invocation, EmbeddingInvocation): - _apply_embedding_finish_attributes(span, invocation) - self._record_metrics(invocation, span) - elif isinstance(invocation, WorkflowInvocation): - _apply_workflow_finish_attributes(span, invocation) - # TODO: Add workflow metrics when supported - finally: - # Detach context and end span even if finishing fails - otel_context.detach(invocation.context_token) - span.end() + .. deprecated:: + Use ``handler.start_inference()`` instead. + """ + invocation._start_with_handler( + self._tracer, self._metrics_recorder, self._logger + ) return invocation - def _fail(self, invocation: _T, error: Error) -> _T: - """Fail a GenAI invocation and end its span with error status.""" - if invocation.context_token is None or invocation.span is None: - # TODO: Provide feedback that this invocation was not started - return invocation - - span = invocation.span - error_type = error.type.__qualname__ - try: - if isinstance(invocation, LLMInvocation): - _apply_llm_finish_attributes(span, invocation) - _apply_error_attributes(span, error, error_type) - self._record_metrics(invocation, span, error_type=error_type) - _maybe_emit_llm_event( - self._logger, span, invocation, error_type - ) - elif isinstance(invocation, EmbeddingInvocation): - _apply_embedding_finish_attributes(span, invocation) - _apply_error_attributes(span, error, error_type) - self._record_metrics(invocation, span, error_type=error_type) - elif isinstance(invocation, WorkflowInvocation): - _apply_workflow_finish_attributes(span, invocation) - _apply_error_attributes(span, error, error_type) - # TODO: Add workflow metrics when supported - finally: - # Detach context and end span even if finishing fails - otel_context.detach(invocation.context_token) - span.end() - return invocation + def start_embedding( + self, + provider: str, + *, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + ) -> EmbeddingInvocation: + """Create and start an Embedding invocation. + + Set remaining attributes (encoding_formats, etc.) on the returned + invocation, then call invocation.stop() or invocation.fail(). + """ + return EmbeddingInvocation( + self._tracer, + self._metrics_recorder, + self._logger, + provider, + request_model=request_model, + server_address=server_address, + server_port=server_port, + ) - def start( + def start_tool( self, - invocation: _T, - ) -> _T: - """Start a GenAI invocation and create a pending span entry.""" - return self._start(invocation) + name: str, + *, + arguments: object = None, + tool_call_id: str | None = None, + tool_type: str | None = None, + tool_description: str | None = None, + ) -> ToolInvocation: + """Create and start a tool invocation. + + Set tool_result on the returned invocation when done, then call + invocation.stop() or invocation.fail(). + """ + return ToolInvocation( + self._tracer, + self._metrics_recorder, + self._logger, + name, + arguments=arguments, + tool_call_id=tool_call_id, + tool_type=tool_type, + tool_description=tool_description, + ) - def stop(self, invocation: _T) -> _T: - """Finalize a GenAI invocation successfully and end its span.""" - return self._stop(invocation) + def start_workflow( + self, + *, + name: str | None = None, + ) -> WorkflowInvocation: + """Create and start a workflow invocation. - def fail(self, invocation: _T, error: Error) -> _T: - """Fail a GenAI invocation and end its span with error status.""" - return self._fail(invocation, error) + Set remaining attributes on the returned invocation, then call + invocation.stop() or invocation.fail(). + """ + return WorkflowInvocation( + self._tracer, self._metrics_recorder, self._logger, name + ) - # LLM-specific convenience methods - def start_llm(self, invocation: LLMInvocation) -> LLMInvocation: - """Start an LLM invocation and create a pending span entry.""" - return self._start(invocation) + def stop_llm(self, invocation: LLMInvocation) -> LLMInvocation: # pylint: disable=no-self-use + """Finalize an LLM invocation successfully and end its span. - def stop_llm(self, invocation: LLMInvocation) -> LLMInvocation: - """Finalize an LLM invocation successfully and end its span.""" - return self._stop(invocation) + .. deprecated:: + Use ``handler.start_inference()`` and then ``inference.stop()`` instead. + """ + invocation._sync_to_invocation() + if invocation._inference_invocation is not None: + invocation._inference_invocation.stop() + return invocation - def fail_llm( - self, invocation: LLMInvocation, error: Error + def fail_llm( # pylint: disable=no-self-use + self, + invocation: LLMInvocation, + error: Error, ) -> LLMInvocation: - """Fail an LLM invocation and end its span with error status.""" - return self._fail(invocation, error) + """Fail an LLM invocation and end its span with error status. - @contextmanager - def llm( - self, invocation: LLMInvocation | None = None - ) -> Iterator[LLMInvocation]: - """Context manager for LLM invocations. + .. deprecated:: + Use ``handler.start_inference()`` and then ``inference.fail()`` instead. + """ + invocation._sync_to_invocation() + if invocation._inference_invocation is not None: + invocation._inference_invocation.fail(error) + return invocation + + def inference( + self, + provider: str, + *, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + ) -> AbstractContextManager[InferenceInvocation]: + """Context manager for LLM inference invocations. Only set data attributes on the invocation object, do not modify the span or context. @@ -288,22 +244,21 @@ def llm( If an exception occurs inside the context, marks the span as error, ends it, and re-raises the original exception. """ - if invocation is None: - invocation = LLMInvocation( - request_model="", - ) - self.start_llm(invocation) - try: - yield invocation - except Exception as exc: - self.fail_llm(invocation, Error(message=str(exc), type=type(exc))) - raise - self.stop_llm(invocation) - - @contextmanager + return self.start_inference( + provider=provider, + request_model=request_model, + server_address=server_address, + server_port=server_port, + )._managed() + def embedding( - self, invocation: EmbeddingInvocation | None = None - ) -> Iterator[EmbeddingInvocation]: + self, + provider: str, + *, + request_model: str | None = None, + server_address: str | None = None, + server_port: int | None = None, + ) -> AbstractContextManager[EmbeddingInvocation]: """Context manager for Embedding invocations. Only set data attributes on the invocation object, do not modify the span or context. @@ -312,20 +267,42 @@ def embedding( If an exception occurs inside the context, marks the span as error, ends it, and re-raises the original exception. """ - if invocation is None: - invocation = EmbeddingInvocation() - self.start(invocation) - try: - yield invocation - except Exception as exc: - self.fail(invocation, Error(message=str(exc), type=type(exc))) - raise - self.stop(invocation) - - @contextmanager + return self.start_embedding( + provider=provider, + request_model=request_model, + server_address=server_address, + server_port=server_port, + )._managed() + + def tool( + self, + name: str, + *, + arguments: object = None, + tool_call_id: str | None = None, + tool_type: str | None = None, + tool_description: str | None = None, + ) -> AbstractContextManager[ToolInvocation]: + """Context manager for Tool invocations. + + Only set data attributes on the invocation object, do not modify the span or context. + + Starts the span on entry. On normal exit, finalizes the invocation and ends the span. + If an exception occurs inside the context, marks the span as error, ends it, and + re-raises the original exception. + """ + return self.start_tool( + name, + arguments=arguments, + tool_call_id=tool_call_id, + tool_type=tool_type, + tool_description=tool_description, + )._managed() + def workflow( - self, invocation: WorkflowInvocation | None = None - ) -> Iterator[WorkflowInvocation]: + self, + name: str | None = None, + ) -> AbstractContextManager[WorkflowInvocation]: """Context manager for Workflow invocations. Only set data attributes on the invocation object, do not modify the span or context. @@ -334,33 +311,7 @@ def workflow( If an exception occurs inside the context, marks the span as error, ends it, and re-raises the original exception. """ - if invocation is None: - invocation = WorkflowInvocation() - - try: - self.start(invocation) - except Exception: # pylint: disable=broad-except - _logger.warning( - "Failed to start workflow telemetry", exc_info=True - ) - - try: - yield invocation - except Exception as exc: - try: - self.fail(invocation, Error(message=str(exc), type=type(exc))) - except Exception: # pylint: disable=broad-except - _logger.warning( - "Failed to record workflow failure", exc_info=True - ) - _safe_detach(invocation) - raise - - try: - self.stop(invocation) - except Exception: # pylint: disable=broad-except - _logger.warning("Failed to stop workflow telemetry", exc_info=True) - _safe_detach(invocation) + return self.start_workflow(name=name)._managed() def get_telemetry_handler( diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/invocation.py new file mode 100644 index 00000000000..4ac6426ce1d --- /dev/null +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/invocation.py @@ -0,0 +1,47 @@ +# 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. + +"""Public re-export of all GenAI invocation types. + +Users can import everything from this single module: + + from opentelemetry.util.genai.invocation import ( + Error, + GenAIInvocation, + InferenceInvocation, + EmbeddingInvocation, + ToolInvocation, + WorkflowInvocation, + ) +""" + +from opentelemetry.util.genai._embedding_invocation import EmbeddingInvocation +from opentelemetry.util.genai._inference_invocation import InferenceInvocation +from opentelemetry.util.genai._invocation import ( + ContextToken, + Error, + GenAIInvocation, +) +from opentelemetry.util.genai._tool_invocation import ToolInvocation +from opentelemetry.util.genai._workflow_invocation import WorkflowInvocation + +__all__ = [ + "ContextToken", + "Error", + "GenAIInvocation", + "InferenceInvocation", + "EmbeddingInvocation", + "ToolInvocation", + "WorkflowInvocation", +] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py index e2ebad64096..144f4663b6e 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/metrics.py @@ -1,29 +1,20 @@ -"""Helpers for emitting GenAI metrics from invocations.""" +"""Helpers for emitting GenAI metrics from LLM invocations.""" from __future__ import annotations import timeit -from typing import Dict, Optional +from typing import Optional from opentelemetry.metrics import Histogram, Meter from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAI, ) -from opentelemetry.semconv.attributes import ( - error_attributes, - server_attributes, -) -from opentelemetry.trace import Span, set_span_in_context from opentelemetry.util.genai.instruments import ( create_duration_histogram, create_token_histogram, ) -from opentelemetry.util.genai.types import ( - EmbeddingInvocation, - GenAIInvocation, - LLMInvocation, -) -from opentelemetry.util.types import AttributeValue + +from ._invocation import GenAIInvocation class InvocationMetricsRecorder: @@ -33,104 +24,31 @@ def __init__(self, meter: Meter): self._duration_histogram: Histogram = create_duration_histogram(meter) self._token_histogram: Histogram = create_token_histogram(meter) - @staticmethod - def _build_attributes( - invocation: GenAIInvocation, - error_type: Optional[str] = None, - ) -> Dict[str, AttributeValue]: - """Build metric attributes from an invocation.""" - attributes: Dict[str, AttributeValue] = {} - - if invocation.operation_name: - attributes[GenAI.GEN_AI_OPERATION_NAME] = invocation.operation_name - - request_model = getattr(invocation, "request_model", None) - if request_model: - attributes[GenAI.GEN_AI_REQUEST_MODEL] = request_model - - if invocation.provider: - attributes[GenAI.GEN_AI_PROVIDER_NAME] = invocation.provider - - response_model_name = getattr(invocation, "response_model_name", None) - if response_model_name: - attributes[GenAI.GEN_AI_RESPONSE_MODEL] = response_model_name - - server_address = getattr(invocation, "server_address", None) - if server_address: - attributes[server_attributes.SERVER_ADDRESS] = server_address - - server_port = getattr(invocation, "server_port", None) - if server_port is not None: - attributes[server_attributes.SERVER_PORT] = server_port - - if invocation.metric_attributes: - attributes.update(invocation.metric_attributes) + def record(self, invocation: GenAIInvocation) -> None: + """Record duration and token metrics for an invocation if possible.""" + attributes = invocation._get_metric_attributes() + token_counts = invocation._get_metric_token_counts() - if error_type: - attributes[error_attributes.ERROR_TYPE] = error_type - - return attributes - - def record( - self, - span: Optional[Span], - invocation: GenAIInvocation, - *, - error_type: Optional[str] = None, - ) -> None: - """Record duration and token metrics for an invocation if possible. - - For LLMInvocation: records duration and token (input/output) metrics. - For EmbeddingInvocation: records duration only. - """ - - # pylint: disable=too-many-branches - - if span is None: - return - - attributes = self._build_attributes(invocation, error_type) - - # Calculate duration from invocation monotonic start duration_seconds: Optional[float] = None - if invocation.monotonic_start_s is not None: + if invocation._monotonic_start_s is not None: duration_seconds = max( - timeit.default_timer() - invocation.monotonic_start_s, + timeit.default_timer() - invocation._monotonic_start_s, 0.0, ) - span_context = set_span_in_context(span) - if duration_seconds is not None: self._duration_histogram.record( duration_seconds, attributes=attributes, - context=span_context, + context=invocation._span_context, ) - # Record token metrics for LLMInvocation and EmbeddingInvocation - if isinstance(invocation, (LLMInvocation, EmbeddingInvocation)): - if invocation.input_tokens is not None: - self._token_histogram.record( - invocation.input_tokens, - attributes=attributes - | { - GenAI.GEN_AI_TOKEN_TYPE: GenAI.GenAiTokenTypeValues.INPUT.value - }, - context=span_context, - ) - - # Only LLMInvocation has output tokens - if isinstance(invocation, LLMInvocation): - if invocation.output_tokens is not None: - self._token_histogram.record( - invocation.output_tokens, - attributes=attributes - | { - GenAI.GEN_AI_TOKEN_TYPE: GenAI.GenAiTokenTypeValues.OUTPUT.value - }, - context=span_context, - ) + for token_type, token_count in token_counts.items(): + self._token_histogram.record( + token_count, + attributes=attributes | {GenAI.GEN_AI_TOKEN_TYPE: token_type}, + context=invocation._span_context, + ) __all__ = ["InvocationMetricsRecorder"] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py deleted file mode 100644 index 0a82462c1bb..00000000000 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py +++ /dev/null @@ -1,417 +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 __future__ import annotations - -from dataclasses import asdict -from typing import Any - -from opentelemetry._logs import Logger, LogRecord -from opentelemetry.context import get_current -from opentelemetry.semconv._incubating.attributes import ( - gen_ai_attributes as GenAI, -) -from opentelemetry.semconv.attributes import ( - error_attributes, - server_attributes, -) -from opentelemetry.trace import ( - Span, -) -from opentelemetry.trace.propagation import set_span_in_context -from opentelemetry.trace.status import Status, StatusCode -from opentelemetry.util.genai.types import ( - EmbeddingInvocation, - Error, - GenAIInvocation, - InputMessage, - LLMInvocation, - MessagePart, - OutputMessage, - WorkflowInvocation, -) -from opentelemetry.util.genai.utils import ( - ContentCapturingMode, - gen_ai_json_dumps, - get_content_capturing_mode, - is_experimental_mode, - should_emit_event, -) - - -def _get_llm_common_attributes( - invocation: LLMInvocation, -) -> dict[str, Any]: - """Get common LLM attributes shared by finish() and error() paths. - - Returns a dictionary of attributes. - """ - # TODO: clean provider name to match GenAiProviderNameValues? - optional_attrs = ( - (GenAI.GEN_AI_REQUEST_MODEL, invocation.request_model), - (GenAI.GEN_AI_PROVIDER_NAME, invocation.provider), - (server_attributes.SERVER_ADDRESS, invocation.server_address), - (server_attributes.SERVER_PORT, invocation.server_port), - ) - - return { - GenAI.GEN_AI_OPERATION_NAME: invocation.operation_name, - **{key: value for key, value in optional_attrs if value is not None}, - } - - -def _get_embedding_common_attributes( - invocation: EmbeddingInvocation, -) -> dict[str, Any]: - """Get common Embedding attributes shared by finish() and error() paths. - - Returns a dictionary of attributes. - """ - optional_attrs = ( - (server_attributes.SERVER_ADDRESS, invocation.server_address), - (server_attributes.SERVER_PORT, invocation.server_port), - ) - - return { - GenAI.GEN_AI_OPERATION_NAME: invocation.operation_name, - GenAI.GEN_AI_PROVIDER_NAME: invocation.provider, - **{key: value for key, value in optional_attrs if value is not None}, - } - - -def _get_span_name( - invocation: GenAIInvocation, -) -> str: - """Get the span name for a GenAI invocation.""" - operation_name = getattr(invocation, "operation_name", None) or "" - request_model = getattr(invocation, "request_model", None) or "" - return f"{operation_name} {request_model}".strip() - - -def _get_llm_span_name(invocation: LLMInvocation) -> str: - """Get the span name for an LLM invocation.""" - return _get_span_name(invocation) - - -def _get_embedding_span_name(invocation: EmbeddingInvocation) -> str: - """Get the span name for an Embedding invocation.""" - return _get_span_name(invocation) - - -def _get_workflow_span_name(invocation: WorkflowInvocation) -> str: - """Get the span name for an Workflow invocation.""" - operation_name = invocation.operation_name - name = invocation.name - return f"{operation_name} {name}" if name else operation_name - - -def _get_messages_attributes_for_span( - input_messages: list[InputMessage], - output_messages: list[OutputMessage], - system_instruction: list[MessagePart] | None = None, -) -> dict[str, Any]: - """Get message attributes formatted for span (JSON string format). - - Returns empty dict if not in experimental mode or content capturing is disabled. - """ - if not is_experimental_mode() or get_content_capturing_mode() not in ( - ContentCapturingMode.SPAN_ONLY, - ContentCapturingMode.SPAN_AND_EVENT, - ): - return {} - - optional_attrs = ( - ( - GenAI.GEN_AI_INPUT_MESSAGES, - gen_ai_json_dumps([asdict(m) for m in input_messages]) - if input_messages - else None, - ), - ( - GenAI.GEN_AI_OUTPUT_MESSAGES, - gen_ai_json_dumps([asdict(m) for m in output_messages]) - if output_messages - else None, - ), - ( - GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, - gen_ai_json_dumps([asdict(p) for p in system_instruction]) - if system_instruction - else None, - ), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _get_llm_messages_attributes_for_event( - input_messages: list[InputMessage], - output_messages: list[OutputMessage], - system_instruction: list[MessagePart] | None = None, -) -> dict[str, Any]: - """Get message attributes formatted for event (structured format). - - Returns empty dict if not in experimental mode or content capturing is disabled. - """ - if not is_experimental_mode() or get_content_capturing_mode() not in ( - ContentCapturingMode.EVENT_ONLY, - ContentCapturingMode.SPAN_AND_EVENT, - ): - return {} - - optional_attrs = ( - ( - GenAI.GEN_AI_INPUT_MESSAGES, - [asdict(m) for m in input_messages] if input_messages else None, - ), - ( - GenAI.GEN_AI_OUTPUT_MESSAGES, - [asdict(m) for m in output_messages] if output_messages else None, - ), - ( - GenAI.GEN_AI_SYSTEM_INSTRUCTIONS, - [asdict(p) for p in system_instruction] - if system_instruction - else None, - ), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _maybe_emit_llm_event( - logger: Logger | None, - span: Span, - invocation: LLMInvocation, - error_type: str | None = None, -) -> None: - """Emit a gen_ai.client.inference.operation.details event to the logger. - - This function creates a LogRecord event following the semantic convention - for gen_ai.client.inference.operation.details as specified in the GenAI - event semantic conventions. - - For more details, see the semantic convention documentation: - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md#event-eventgen_aiclientinferenceoperationdetails - """ - if not is_experimental_mode() or not should_emit_event() or logger is None: - return - - # Build event attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_llm_common_attributes(invocation)) - attributes.update(_get_llm_request_attributes(invocation)) - attributes.update(_get_llm_response_attributes(invocation)) - attributes.update( - _get_llm_messages_attributes_for_event( - invocation.input_messages, - invocation.output_messages, - invocation.system_instruction, - ) - ) - - # Add error.type if operation ended in error - if error_type is not None: - attributes[error_attributes.ERROR_TYPE] = error_type - - # Create and emit the event - context = set_span_in_context(span, get_current()) - event = LogRecord( - event_name="gen_ai.client.inference.operation.details", - attributes=attributes, - context=context, - ) - logger.emit(event) - - -def _apply_llm_finish_attributes( - span: Span, invocation: LLMInvocation -) -> None: - """Apply attributes/messages common to finish() paths.""" - # Update span name - span.update_name(_get_llm_span_name(invocation)) - - # Build all attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_llm_common_attributes(invocation)) - attributes.update(_get_llm_request_attributes(invocation)) - attributes.update(_get_llm_response_attributes(invocation)) - attributes.update( - _get_messages_attributes_for_span( - invocation.input_messages, - invocation.output_messages, - invocation.system_instruction, - ) - ) - attributes.update(invocation.attributes) - - # Set all attributes on the span - if attributes: - span.set_attributes(attributes) - - -def _apply_embedding_finish_attributes( - span: Span, invocation: EmbeddingInvocation -) -> None: - """Apply attributes common to embedding finish() paths.""" - # Update span name - span.update_name(_get_embedding_span_name(invocation)) - - # Build all attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_embedding_common_attributes(invocation)) - attributes.update(_get_embedding_request_attributes(invocation)) - attributes.update(_get_embedding_response_attributes(invocation)) - - attributes.update(invocation.attributes) - - # Set all attributes on the span - if attributes: - span.set_attributes(attributes) - - -def _apply_error_attributes(span: Span, error: Error, error_type: str) -> None: - """Apply status and error attributes common to error() paths.""" - span.set_status(Status(StatusCode.ERROR, error.message)) - if span.is_recording(): - span.set_attribute(error_attributes.ERROR_TYPE, error_type) - - -def _get_llm_request_attributes( - invocation: LLMInvocation, -) -> dict[str, Any]: - """Get GenAI request semantic convention attributes.""" - optional_attrs = ( - (GenAI.GEN_AI_REQUEST_TEMPERATURE, invocation.temperature), - (GenAI.GEN_AI_REQUEST_TOP_P, invocation.top_p), - (GenAI.GEN_AI_REQUEST_FREQUENCY_PENALTY, invocation.frequency_penalty), - (GenAI.GEN_AI_REQUEST_PRESENCE_PENALTY, invocation.presence_penalty), - (GenAI.GEN_AI_REQUEST_MAX_TOKENS, invocation.max_tokens), - (GenAI.GEN_AI_REQUEST_STOP_SEQUENCES, invocation.stop_sequences), - (GenAI.GEN_AI_REQUEST_SEED, invocation.seed), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _get_embedding_request_attributes( - invocation: EmbeddingInvocation, -) -> dict[str, Any]: - """Get GenAI request semantic convention attributes.""" - optional_attrs = ( - (GenAI.GEN_AI_REQUEST_MODEL, invocation.request_model), - (GenAI.GEN_AI_EMBEDDINGS_DIMENSION_COUNT, invocation.dimension_count), - (GenAI.GEN_AI_REQUEST_ENCODING_FORMATS, invocation.encoding_formats), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _get_llm_response_attributes( - invocation: LLMInvocation, -) -> dict[str, Any]: - """Get GenAI response semantic convention attributes.""" - finish_reasons: list[str] | None - if invocation.finish_reasons is not None: - finish_reasons = invocation.finish_reasons - elif invocation.output_messages: - finish_reasons = [ - message.finish_reason - for message in invocation.output_messages - if message.finish_reason - ] - else: - finish_reasons = None - - # De-duplicate finish reasons - unique_finish_reasons = ( - sorted(set(finish_reasons)) if finish_reasons else None - ) - - optional_attrs = ( - ( - GenAI.GEN_AI_RESPONSE_FINISH_REASONS, - unique_finish_reasons if unique_finish_reasons else None, - ), - (GenAI.GEN_AI_RESPONSE_MODEL, invocation.response_model_name), - (GenAI.GEN_AI_RESPONSE_ID, invocation.response_id), - (GenAI.GEN_AI_USAGE_INPUT_TOKENS, invocation.input_tokens), - (GenAI.GEN_AI_USAGE_OUTPUT_TOKENS, invocation.output_tokens), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -def _apply_workflow_finish_attributes( - span: Span, invocation: WorkflowInvocation -) -> None: - """Apply attributes/messages common to finish() paths.""" - - # Build all attributes by reusing the attribute getter functions - attributes: dict[str, Any] = {} - attributes.update(_get_workflow_common_attributes(invocation)) - attributes.update( - _get_messages_attributes_for_span( - invocation.input_messages, - invocation.output_messages, - ) - ) - attributes.update(invocation.attributes) - - # Set all attributes on the span - if attributes: - span.set_attributes(attributes) - - -def _get_workflow_common_attributes( - invocation: WorkflowInvocation, -) -> dict[str, Any]: - """Get common Workflow attributes shared by finish() and error() paths. - - Returns a dictionary of attributes. - """ - return { - GenAI.GEN_AI_OPERATION_NAME: invocation.operation_name, - } - - -def _get_embedding_response_attributes( - invocation: EmbeddingInvocation, -) -> dict[str, Any]: - """Get GenAI response semantic convention attributes.""" - optional_attrs = ( - (GenAI.GEN_AI_RESPONSE_MODEL, invocation.response_model_name), - (GenAI.GEN_AI_USAGE_INPUT_TOKENS, invocation.input_tokens), - ) - - return {key: value for key, value in optional_attrs if value is not None} - - -__all__ = [ - "_apply_llm_finish_attributes", - "_apply_error_attributes", - "_get_llm_common_attributes", - "_get_llm_request_attributes", - "_get_llm_response_attributes", - "_get_llm_span_name", - "_maybe_emit_llm_event", - "_get_workflow_common_attributes", - "_apply_workflow_finish_attributes", - "_apply_embedding_finish_attributes", - "_get_embedding_common_attributes", - "_get_embedding_request_attributes", - "_get_embedding_response_attributes", - "_get_embedding_span_name", - "_get_workflow_span_name", -] diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py index 35f8473f0c2..103c168023b 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py @@ -14,20 +14,28 @@ from __future__ import annotations -from contextvars import Token -from dataclasses import dataclass, field +from dataclasses import dataclass from enum import Enum -from typing import Any, Literal, Type, Union +from typing import TYPE_CHECKING, Any, Literal, Type, Union -from typing_extensions import TypeAlias +if TYPE_CHECKING: + from opentelemetry.util.genai._inference_invocation import ( # pylint: disable=useless-import-alias + LLMInvocation as LLMInvocation, # noqa: PLC0414 + ) + from opentelemetry.util.genai._invocation import ( # pylint: disable=useless-import-alias + GenAIInvocation as GenAIInvocation, # noqa: PLC0414 + ) -from opentelemetry.context import Context -from opentelemetry.semconv._incubating.attributes import ( - gen_ai_attributes as GenAI, -) -from opentelemetry.trace import Span -ContextToken: TypeAlias = Token[Context] +class ContentCapturingMode(Enum): + # Do not capture content (default). + NO_CONTENT = 0 + # Only capture content in spans. + SPAN_ONLY = 1 + # Only capture content in events. + EVENT_ONLY = 2 + # Capture content in both spans and events. + SPAN_AND_EVENT = 3 @dataclass() @@ -41,23 +49,12 @@ class GenericPart: type: Literal["generic"] = "generic" -class ContentCapturingMode(Enum): - # Do not capture content (default). - NO_CONTENT = 0 - # Only capture content in spans. - SPAN_ONLY = 1 - # Only capture content in events. - EVENT_ONLY = 2 - # Capture content in both spans and events. - SPAN_AND_EVENT = 3 - - @dataclass() class ToolCallRequest: """Represents a tool call requested by the model (message part only). Use this for tool calls in message history. For execution tracking with spans - and metrics, use ToolCall instead. + and metrics, use ToolInvocation instead. This model is specified as part of semconv in `GenAI messages Python models - ToolCallRequestPart `__. @@ -84,7 +81,7 @@ class ToolCallResponse: @dataclass() class ServerToolCall: - """Represents a server-side tool call invocation. + """Represents a server-side tool call. Server tool calls are executed by the model provider on the server side rather than by the client application. Provider-specific tools (e.g., code_interpreter, @@ -238,183 +235,21 @@ class OutputMessage: finish_reason: str | FinishReason -def _new_input_messages() -> list[InputMessage]: - return [] - - -def _new_output_messages() -> list[OutputMessage]: - return [] - - -def _new_system_instruction() -> list[MessagePart]: - return [] - - -def _new_str_any_dict() -> dict[str, Any]: - return {} - - -@dataclass -class GenAIInvocation: - operation_name: str = "" - provider: str | None = None - context_token: ContextToken | None = None - span: Span | None = None - attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) - metric_attributes: dict[str, Any] = field( - default_factory=_new_str_any_dict - ) - """ - Additional attributes to set on metrics. Must be of a low cardinality. - These attributes will not be set on spans or events. - """ - error_type: str | None = None - - monotonic_start_s: float | None = None - """ - Monotonic start time in seconds (from timeit.default_timer) used for - duration calculations to avoid mixing clock sources. This is populated - by the TelemetryHandler when starting an invocation. - """ - - @dataclass -class WorkflowInvocation(GenAIInvocation): - """ - Represents predetermined static sequence of operations eg: Agent, LLM, tool, and retrieval invocations. - A workflow groups multiple operations together, accepting input(s) and producing final output(s). - """ - - name: str = "" - operation_name: str = "invoke_workflow" - input_messages: list[InputMessage] = field( - default_factory=_new_input_messages - ) - output_messages: list[OutputMessage] = field( - default_factory=_new_output_messages - ) - - def __post_init__(self) -> None: - self.operation_name = "invoke_workflow" - - -@dataclass -class LLMInvocation(GenAIInvocation): - """ - Represents a single LLM call invocation. When creating an LLMInvocation object, - only update the data attributes. The span and context_token attributes are - set by the TelemetryHandler. - """ - - operation_name: str = GenAI.GenAiOperationNameValues.CHAT.value - request_model: str | None = None - input_messages: list[InputMessage] = field( - default_factory=_new_input_messages - ) - output_messages: list[OutputMessage] = field( - default_factory=_new_output_messages - ) - system_instruction: list[MessagePart] = field( - default_factory=_new_system_instruction - ) - provider: str | None = None - response_model_name: str | None = None - response_id: str | None = None - finish_reasons: list[str] | None = None - input_tokens: int | None = None - output_tokens: int | None = None - attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) - """ - Additional attributes to set on spans and/or events. These attributes - will not be set on metrics. - """ - temperature: float | None = None - top_p: float | None = None - frequency_penalty: float | None = None - presence_penalty: float | None = None - max_tokens: int | None = None - stop_sequences: list[str] | None = None - seed: int | None = None - server_address: str | None = None - server_port: int | None = None - - -@dataclass -class EmbeddingInvocation(GenAIInvocation): - """ - Represents a single embedding model invocation. When creating an - EmbeddingInvocation object, only update the data attributes. The span - and context_token attributes are set by the TelemetryHandler. - """ - - operation_name: str = GenAI.GenAiOperationNameValues.EMBEDDINGS.value - request_model: str | None = None - provider: str | None = None # e.g., azure.ai.openai, openai, aws.bedrock - server_address: str | None = None - server_port: int | None = None - - # encoding_formats can be multi-value -> combinational cardinality risk. - # Keep on spans/events only. - encoding_formats: list[str] | None = None - input_tokens: int | None = None - dimension_count: int | None = None - response_model_name: str | None = None - - attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) - """ - Additional attributes to set on spans and/or events. These attributes - will not be set on metrics. - """ - - -@dataclass() -class ToolCall(GenAIInvocation): - """Represents a tool call for execution tracking with spans and metrics. - - This type extends GenAIInvocation (like LLMInvocation) for consistent lifecycle - management across all invocation types. It is NOT used as a MessagePart directly - - use ToolCallRequest for that purpose. - - Inherits from GenAIInvocation: - - context_token: Context tracking for span lifecycle - - span: Active span reference - - attributes: Custom attributes dict for extensibility - - Reference: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md#execute-tool-span - - Semantic convention attributes for execute_tool spans: - - gen_ai.operation.name: "execute_tool" (Required) - - gen_ai.tool.name: Name of the tool (Recommended) - - gen_ai.tool.call.id: Tool call identifier (Recommended if available) - - gen_ai.tool.type: Type classification - "function", "extension", or "datastore" (Recommended if available) - - gen_ai.tool.description: Tool description (Recommended if available) - - gen_ai.tool.call.arguments: Parameters passed to tool (Opt-In, may contain sensitive data) - - gen_ai.tool.call.result: Result returned by tool (Opt-In, may contain sensitive data) - - error.type: Error type if operation failed (Conditionally Required) - """ - - operation_name: str = GenAI.GenAiOperationNameValues.EXECUTE_TOOL.value - - # Message identification fields (same as ToolCallRequest) - # Note: These are required fields but must have defaults due to dataclass inheritance - name: str = "" - arguments: Any = None - id: str | None = None - type: Literal["tool_call"] = "tool_call" +class Error: + message: str + type: Type[BaseException] - # Execution tracking fields (used for execute_tool spans): - # gen_ai.tool.type - Tool type: "function", "extension", or "datastore" - tool_type: str | None = None - # gen_ai.tool.description - Description of what the tool does - tool_description: str | None = None - # gen_ai.tool.call.result - Result returned by the tool (Opt-In, may contain sensitive data) - tool_result: Any = None - # Timing field (not inherited from GenAIInvocation, matches LLMInvocation pattern) - monotonic_start_s: float | None = None +def __getattr__(name: str) -> object: + if name == "GenAIInvocation": + import opentelemetry.util.genai.invocation as _inv # noqa: PLC0415 # pylint: disable=import-outside-toplevel + return _inv.GenAIInvocation + if name == "LLMInvocation": + from opentelemetry.util.genai._inference_invocation import ( # noqa: PLC0415 # pylint: disable=import-outside-toplevel + LLMInvocation, + ) -@dataclass -class Error: - message: str - type: Type[BaseException] + return LLMInvocation + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/util/opentelemetry-util-genai/tests/test_handler_metrics.py b/util/opentelemetry-util-genai/tests/test_handler_metrics.py index 3b16a1ec1d9..b28ed96bf50 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_metrics.py +++ b/util/opentelemetry-util-genai/tests/test_handler_metrics.py @@ -9,11 +9,7 @@ from opentelemetry.semconv.schemas import Schemas from opentelemetry.test.test_base import TestBase from opentelemetry.util.genai.handler import TelemetryHandler -from opentelemetry.util.genai.types import ( - EmbeddingInvocation, - Error, - LLMInvocation, -) +from opentelemetry.util.genai.types import Error _DEFAULT_SCHEMA_URL = Schemas.V1_37_0.value @@ -26,19 +22,18 @@ def test_stop_llm_records_duration_and_tokens(self) -> None: tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, ) - invocation = LLMInvocation(request_model="model", provider="prov") - invocation.input_tokens = 5 - invocation.output_tokens = 7 # Patch default_timer during start to ensure monotonic_start_s with patch("timeit.default_timer", return_value=1000.0): - handler.start_llm(invocation) + invocation = handler.start_inference("prov", request_model="model") + invocation.input_tokens = 5 + invocation.output_tokens = 7 # Simulate 2 seconds of elapsed monotonic time (seconds) with patch( "timeit.default_timer", return_value=1002.0, ): - handler.stop_llm(invocation) + invocation.stop() self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -84,17 +79,19 @@ def test_stop_llm_records_duration_and_tokens_with_additional_attributes( meter_provider=self.meter_provider, ) - invocation = LLMInvocation(request_model="model", provider="prov") + invocation = handler.start_inference( + "prov", + request_model="model", + server_address="custom.server.com", + server_port=42, + ) invocation.input_tokens = 5 invocation.output_tokens = 7 - invocation.server_address = "custom.server.com" - invocation.server_port = 42 - handler.start_llm(invocation) invocation.metric_attributes = { "custom.attribute": "custom_value", } invocation.attributes = {"should not be on metrics": "value"} - handler.stop_llm(invocation) + invocation.stop() self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -119,18 +116,17 @@ def test_fail_llm_records_error_and_available_tokens(self) -> None: tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, ) - invocation = LLMInvocation(request_model="err-model", provider=None) - invocation.input_tokens = 11 # Patch default_timer during start to ensure monotonic_start_s with patch("timeit.default_timer", return_value=2000.0): - handler.start_llm(invocation) + invocation = handler.start_inference("", request_model="err-model") + invocation.input_tokens = 11 error = Error(message="boom", type=ValueError) with patch( "timeit.default_timer", return_value=2001.0, ): - handler.fail_llm(invocation, error) + invocation.fail(error) self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -166,7 +162,7 @@ def _harvest_metrics( resource_metrics is the raw ResourceMetrics list for scope-level assertions (e.g. schema_url). """ - metrics = self.get_sorted_metrics(SCOPE) + metrics = self.get_sorted_metrics() metrics_by_name: Dict[str, List[Any]] = {} for metric in metrics or []: points = metric.data.data_points or [] diff --git a/util/opentelemetry-util-genai/tests/test_handler_workflow.py b/util/opentelemetry-util-genai/tests/test_handler_workflow.py index d3af4e9ec75..3bf689a14b8 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_workflow.py +++ b/util/opentelemetry-util-genai/tests/test_handler_workflow.py @@ -13,15 +13,15 @@ from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAI, ) -from opentelemetry.trace import SpanKind +from opentelemetry.trace import INVALID_SPAN, SpanKind from opentelemetry.trace.status import StatusCode from opentelemetry.util.genai.handler import TelemetryHandler +from opentelemetry.util.genai.invocation import WorkflowInvocation from opentelemetry.util.genai.types import ( Error, InputMessage, OutputMessage, Text, - WorkflowInvocation, ) @@ -47,71 +47,55 @@ class TelemetryHandlerWorkflowTest(_WorkflowTestBase): # start_workflow # ------------------------------------------------------------------ - def test_operation_name_is_immutable(self) -> None: - invocation = WorkflowInvocation(name="wf", operation_name="custom_op") - self.assertEqual(invocation.operation_name, "invoke_workflow") - def test_start_workflow_creates_span(self) -> None: - invocation = WorkflowInvocation(name="my_workflow") - self.handler.start(invocation) - - self.assertIsNotNone(invocation.span) - self.assertIsNotNone(invocation.context_token) - self.assertIsNotNone(invocation.monotonic_start_s) - - # Clean up - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="my_workflow") + self.assertIsNot(invocation.span, INVALID_SPAN) + invocation.stop() def test_start_workflow_span_name(self) -> None: - invocation = WorkflowInvocation(name="my_pipeline") - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="my_pipeline") + invocation.stop() spans = self._get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual(spans[0].name, "invoke_workflow my_pipeline") def test_start_workflow_span_name_without_name(self) -> None: - invocation = WorkflowInvocation() - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name=None) + invocation.stop() spans = self._get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual(spans[0].name, "invoke_workflow") def test_start_workflow_span_kind_is_internal(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="wf") + invocation.stop() spans = self._get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual(spans[0].kind, SpanKind.INTERNAL) def test_start_workflow_records_monotonic_start(self) -> None: - invocation = WorkflowInvocation(name="wf") with patch("timeit.default_timer", return_value=500.0): - self.handler.start(invocation) - self.assertEqual(invocation.monotonic_start_s, 500.0) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="wf") + self.assertEqual(invocation._monotonic_start_s, 500.0) + invocation.stop() # ------------------------------------------------------------------ # stop_workflow # ------------------------------------------------------------------ def test_stop_workflow_ends_span(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="wf") + invocation.stop() spans = self._get_finished_spans() self.assertEqual(len(spans), 1) def test_stop_workflow_sets_operation_name_attribute(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - self.handler.stop(invocation) + invocation = self.handler.start_workflow(name="wf") + invocation.stop() spans = self._get_finished_spans() self.assertEqual( @@ -120,36 +104,27 @@ def test_stop_workflow_sets_operation_name_attribute(self) -> None: ) def test_stop_workflow_sets_custom_attributes(self) -> None: - invocation = WorkflowInvocation(name="wf") + invocation = self.handler.start_workflow(name="wf") invocation.attributes["custom.key"] = "custom_value" - self.handler.start(invocation) - self.handler.stop(invocation) + invocation.stop() spans = self._get_finished_spans() self.assertEqual(spans[0].attributes["custom.key"], "custom_value") - def test_stop_workflow_noop_when_not_started(self) -> None: - invocation = WorkflowInvocation(name="wf") - # Not started — span and context_token are None - result = self.handler.stop(invocation) - self.assertIs(result, invocation) - self.assertEqual(len(self._get_finished_spans()), 0) - def test_stop_workflow_returns_invocation(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - result = self.handler.stop(invocation) - self.assertIs(result, invocation) + invocation = self.handler.start_workflow(name="wf") + invocation.stop() + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) # ------------------------------------------------------------------ # fail_workflow # ------------------------------------------------------------------ def test_fail_workflow_sets_error_status(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) + invocation = self.handler.start_workflow(name="wf") error = Error(message="something broke", type=RuntimeError) - self.handler.fail(invocation, error) + invocation.fail(error) spans = self._get_finished_spans() self.assertEqual(len(spans), 1) @@ -157,19 +132,17 @@ def test_fail_workflow_sets_error_status(self) -> None: self.assertEqual(spans[0].status.description, "something broke") def test_fail_workflow_sets_error_type_attribute(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) + invocation = self.handler.start_workflow(name="wf") error = Error(message="bad", type=ValueError) - self.handler.fail(invocation, error) + invocation.fail(error) spans = self._get_finished_spans() self.assertEqual(spans[0].attributes["error.type"], "ValueError") def test_fail_workflow_sets_operation_name_attribute(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) + invocation = self.handler.start_workflow(name="wf") error = Error(message="fail", type=TypeError) - self.handler.fail(invocation, error) + invocation.fail(error) spans = self._get_finished_spans() self.assertEqual( @@ -177,19 +150,12 @@ def test_fail_workflow_sets_operation_name_attribute(self) -> None: "invoke_workflow", ) - def test_fail_workflow_noop_when_not_started(self) -> None: - invocation = WorkflowInvocation(name="wf") - error = Error(message="fail", type=RuntimeError) - result = self.handler.fail(invocation, error) - self.assertIs(result, invocation) - self.assertEqual(len(self._get_finished_spans()), 0) - - def test_fail_workflow_returns_invocation(self) -> None: - invocation = WorkflowInvocation(name="wf") - self.handler.start(invocation) - error = Error(message="err", type=RuntimeError) - result = self.handler.fail(invocation, error) - self.assertIs(result, invocation) + def test_fail_workflow_ends_span(self) -> None: + invocation = self.handler.start_workflow(name="wf") + invocation.fail(Error(message="err", type=RuntimeError)) + spans = self._get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual(spans[0].status.status_code, StatusCode.ERROR) class TelemetryHandlerWorkflowContextManagerTest(_WorkflowTestBase): @@ -198,10 +164,8 @@ class TelemetryHandlerWorkflowContextManagerTest(_WorkflowTestBase): # ------------------------------------------------------------------ def test_workflow_context_manager_creates_and_ends_span(self) -> None: - invocation = WorkflowInvocation(name="ctx_wf") - with self.handler.workflow(invocation) as inv: - self.assertIsNotNone(inv.span) - self.assertIsNotNone(inv.context_token) + with self.handler.workflow(name="ctx_wf") as inv: + self.assertIsNot(inv.span, INVALID_SPAN) spans = self._get_finished_spans() self.assertEqual(len(spans), 1) @@ -210,30 +174,27 @@ def test_workflow_context_manager_creates_and_ends_span(self) -> None: def test_workflow_context_manager_default_invocation(self) -> None: with self.handler.workflow() as inv: self.assertIsInstance(inv, WorkflowInvocation) - self.assertEqual(inv.name, "") - self.assertEqual(inv.operation_name, "invoke_workflow") + self.assertIsNone(inv.name) + self.assertEqual(inv._operation_name, "invoke_workflow") spans = self._get_finished_spans() self.assertEqual(len(spans), 1) def test_workflow_context_manager_sets_attributes_on_span(self) -> None: - invocation = WorkflowInvocation(name="wf") - with self.handler.workflow(invocation) as inv: + with self.handler.workflow("wf") as inv: inv.attributes["my.attr"] = "hello" spans = self._get_finished_spans() self.assertEqual(spans[0].attributes["my.attr"], "hello") def test_workflow_context_manager_reraises_exception(self) -> None: - invocation = WorkflowInvocation(name="wf") with pytest.raises(ValueError, match="test error"): - with self.handler.workflow(invocation): + with self.handler.workflow("wf"): raise ValueError("test error") def test_workflow_context_manager_marks_error_on_exception(self) -> None: - invocation = WorkflowInvocation(name="wf") with pytest.raises(ValueError): - with self.handler.workflow(invocation): + with self.handler.workflow("wf"): raise ValueError("boom") spans = self._get_finished_spans() @@ -243,8 +204,7 @@ def test_workflow_context_manager_marks_error_on_exception(self) -> None: self.assertEqual(spans[0].attributes["error.type"], "ValueError") def test_workflow_context_manager_success_has_unset_status(self) -> None: - invocation = WorkflowInvocation(name="wf") - with self.handler.workflow(invocation): + with self.handler.workflow("wf"): pass spans = self._get_finished_spans() @@ -255,13 +215,9 @@ def test_workflow_context_manager_with_messages(self) -> None: out = OutputMessage( role="assistant", parts=[Text(content="hi")], finish_reason="stop" ) - invocation = WorkflowInvocation( - name="msg_wf", - input_messages=[inp], - output_messages=[out], - ) - with self.handler.workflow(invocation): - pass + with self.handler.workflow("msg_wf") as inv: + inv.input_messages = [inp] + inv.output_messages = [out] spans = self._get_finished_spans() self.assertEqual(len(spans), 1) @@ -269,42 +225,3 @@ def test_workflow_context_manager_with_messages(self) -> None: spans[0].attributes[GenAI.GEN_AI_OPERATION_NAME], "invoke_workflow", ) - - def test_workflow_context_manager_swallows_start_failure(self) -> None: - """workflow() should yield even if start_workflow raises.""" - invocation = WorkflowInvocation(name="wf") - with patch.object( - self.handler, - "start", - side_effect=RuntimeError("start failed"), - ): - # Should not raise — the exception is swallowed with a warning - with self.handler.workflow(invocation) as inv: - self.assertIs(inv, invocation) - - def test_workflow_context_manager_swallows_stop_failure(self) -> None: - """workflow() should not raise if stop_workflow fails.""" - invocation = WorkflowInvocation(name="wf") - with patch.object( - self.handler, - "stop", - side_effect=RuntimeError("stop failed"), - ): - # Should not raise - with self.handler.workflow(invocation): - pass - - def test_workflow_context_manager_swallows_fail_workflow_failure( - self, - ) -> None: - """workflow() should still re-raise the original exception even if - fail_workflow itself raises.""" - invocation = WorkflowInvocation(name="wf") - with patch.object( - self.handler, - "fail", - side_effect=RuntimeError("fail broke"), - ): - with pytest.raises(ValueError, match="original"): - with self.handler.workflow(invocation): - raise ValueError("original") diff --git a/util/opentelemetry-util-genai/tests/test_toolcall.py b/util/opentelemetry-util-genai/tests/test_toolcall.py index d076f5e72bc..abf7f637ae1 100644 --- a/util/opentelemetry-util-genai/tests/test_toolcall.py +++ b/util/opentelemetry-util-genai/tests/test_toolcall.py @@ -12,20 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Tests for ToolCallRequest and ToolCall inheritance structure""" +"""Tests for ToolCallRequest and ToolInvocation inheritance structure""" import pytest +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.util.genai.handler import TelemetryHandler +from opentelemetry.util.genai.invocation import GenAIInvocation from opentelemetry.util.genai.types import ( - GenAIInvocation, InputMessage, ServerToolCall, ServerToolCallResponse, - ToolCall, ToolCallRequest, ) +def _make_handler() -> TelemetryHandler: + return TelemetryHandler(tracer_provider=TracerProvider()) + + def test_toolcallrequest_is_message_part(): """ToolCallRequest is for message parts only""" tcr = ToolCallRequest( @@ -36,25 +41,40 @@ def test_toolcallrequest_is_message_part(): def test_toolcall_inherits_from_genaiinvocation(): - """ToolCall inherits from GenAIInvocation for lifecycle management""" - tc = ToolCall(name="get_weather", arguments={"city": "Paris"}) + """ToolInvocation inherits from GenAIInvocation for lifecycle management""" + handler = _make_handler() + tc = handler.start_tool("get_weather", arguments={"city": "Paris"}) assert isinstance(tc, GenAIInvocation) assert not isinstance(tc, ToolCallRequest) + tc.stop() def test_toolcall_has_attributes_dict(): - """ToolCall inherits attributes dict from GenAIInvocation""" - tc = ToolCall(name="test") + """ToolInvocation inherits attributes dict from GenAIInvocation""" + handler = _make_handler() + tc = handler.start_tool("test") tc.attributes["custom.key"] = "value" assert tc.attributes["custom.key"] == "value" + tc.stop() -def test_toolcall_in_message_part_union(): - """ToolCall can be used in messages despite not inheriting from ToolCallRequest""" - tc = ToolCall(name="get_weather", arguments={"city": "Paris"}) +def test_toolcallrequest_in_message_part_union(): + """ToolCallRequest (not ToolInvocation) is the correct type for message parts""" + tc = ToolCallRequest( + name="get_weather", arguments={"city": "Paris"}, id="call_123" + ) msg = InputMessage(role="assistant", parts=[tc]) assert len(msg.parts) == 1 - assert isinstance(msg.parts[0], GenAIInvocation) + assert isinstance(msg.parts[0], ToolCallRequest) + assert not isinstance(msg.parts[0], GenAIInvocation) + + +def test_toolcall_operation_name(): + """ToolInvocation operation_name is fixed to execute_tool""" + handler = _make_handler() + tc = handler.start_tool("my_tool") + assert tc._operation_name == "execute_tool" + tc.stop() def test_server_tool_call_basic(): diff --git a/util/opentelemetry-util-genai/tests/test_utils.py b/util/opentelemetry-util-genai/tests/test_utils.py index ee0e63d852d..31629c5b0c4 100644 --- a/util/opentelemetry-util-genai/tests/test_utils.py +++ b/util/opentelemetry-util-genai/tests/test_utils.py @@ -49,9 +49,7 @@ from opentelemetry.util.genai.handler import get_telemetry_handler from opentelemetry.util.genai.types import ( ContentCapturingMode, - EmbeddingInvocation, InputMessage, - LLMInvocation, MessagePart, OutputMessage, Text, @@ -248,25 +246,23 @@ def test_llm_start_and_stop_creates_span(self): # pylint: disable=no-self-use chat_generation = _create_output_message("hello back") system_instruction = _create_system_instruction() - with self.telemetry_handler.llm() as invocation: - for attr, value in { - "request_model": "test-model", - "input_messages": [message], - "system_instruction": system_instruction, - "provider": "test-provider", - "attributes": {"custom_attr": "value"}, - "temperature": 0.5, - "top_p": 0.9, - "stop_sequences": ["stop"], - "finish_reasons": ["stop"], - "response_model_name": "test-response-model", - "response_id": "response-id", - "input_tokens": 321, - "output_tokens": 654, - "server_address": "custom.server.com", - "server_port": 42, - }.items(): - setattr(invocation, attr, value) + with self.telemetry_handler.inference( + "test-provider", + request_model="test-model", + server_address="custom.server.com", + server_port=42, + ) as invocation: + invocation.input_messages = [message] + invocation.system_instruction = system_instruction + invocation.attributes = {"custom_attr": "value"} + invocation.temperature = 0.5 + invocation.top_p = 0.9 + invocation.stop_sequences = ["stop"] + invocation.finish_reasons = ["stop"] + invocation.response_model_name = "test-response-model" + invocation.response_id = "response-id" + invocation.input_tokens = 321 + invocation.output_tokens = 654 assert invocation.span is not None invocation.output_messages = [chat_generation] invocation.attributes.update({"extra": "info"}) @@ -331,18 +327,15 @@ def test_llm_manual_start_and_stop_creates_span(self): message = _create_input_message("hi") chat_generation = _create_output_message("ok") - invocation = LLMInvocation( - request_model="manual-model", - input_messages=[message], - provider="test-provider", - attributes={"manual": True}, + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="manual-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] + invocation.attributes["manual"] = True assert invocation.span is not None invocation.output_messages = [chat_generation] invocation.attributes.update({"extra_manual": "yes"}) - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) assert span.name == "chat manual-model" @@ -365,19 +358,16 @@ def test_llm_manual_start_and_stop_creates_span(self): ) def test_llm_span_finish_reasons_without_output_messages(self): - invocation = LLMInvocation( - request_model="model-without-output", - provider="test-provider", - finish_reasons=["length"], - response_model_name="alt-model", - response_id="resp-001", - input_tokens=12, - output_tokens=34, - ) - - self.telemetry_handler.start_llm(invocation) + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="model-without-output" + ) + invocation.finish_reasons = ["length"] + invocation.response_model_name = "alt-model" + invocation.response_id = "resp-001" + invocation.input_tokens = 12 + invocation.output_tokens = 34 assert invocation.span is not None - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) _assert_span_time_order(span) @@ -396,55 +386,46 @@ def test_llm_span_finish_reasons_without_output_messages(self): }, ) - def test_llm_span_finish_reasons_deduplicated_from_invocation(self): - invocation = LLMInvocation( - request_model="model-dedup", - provider="test-provider", - finish_reasons=["stop", "length", "stop"], + def test_llm_span_finish_reasons_from_invocation(self): + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="model-reasons" ) - - self.telemetry_handler.start_llm(invocation) + invocation.finish_reasons = ["stop", "length", "stop"] assert invocation.span is not None - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) attrs = _get_span_attributes(span) self.assertEqual( attrs[GenAI.GEN_AI_RESPONSE_FINISH_REASONS], - ("length", "stop"), + ("stop", "length", "stop"), ) - def test_llm_span_finish_reasons_deduplicated_from_output_messages(self): - invocation = LLMInvocation( - request_model="model-output-dedup", - provider="test-provider", + def test_llm_span_finish_reasons_from_output_messages(self): + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="model-output-reasons" ) - - self.telemetry_handler.start_llm(invocation) assert invocation.span is not None invocation.output_messages = [ _create_output_message("response-1", finish_reason="stop"), _create_output_message("response-2", finish_reason="length"), _create_output_message("response-3", finish_reason="stop"), ] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) attrs = _get_span_attributes(span) self.assertEqual( attrs[GenAI.GEN_AI_RESPONSE_FINISH_REASONS], - ("length", "stop"), + ("stop", "length", "stop"), ) def test_llm_span_uses_expected_schema_url(self): - invocation = LLMInvocation( - request_model="schema-model", - provider="schema-provider", + invocation = self.telemetry_handler.start_inference( + "schema-provider", request_model="schema-model" ) - - self.telemetry_handler.start_llm(invocation) assert invocation.span is not None - self.telemetry_handler.stop_llm(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) instrumentation = getattr(span, "instrumentation_scope", None) @@ -463,14 +444,11 @@ def test_llm_span_uses_expected_schema_url(self): emit_event="true", ) def test_llm_log_uses_expected_schema_url(self): - invocation = LLMInvocation( - request_model="schema-model", - provider="schema-provider", + invocation = self.telemetry_handler.start_inference( + "schema-provider", request_model="schema-model" ) - - self.telemetry_handler.start_llm(invocation) invocation.output_messages = [_create_output_message()] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() logs = self.log_exporter.get_finished_logs() self.assertEqual(len(logs), 1) @@ -487,20 +465,14 @@ def test_parent_child_span_relationship(self): message = _create_input_message("hi") chat_generation = _create_output_message("ok") - with self.telemetry_handler.llm() as parent_invocation: - for attr, value in { - "request_model": "parent-model", - "input_messages": [message], - "provider": "test-provider", - }.items(): - setattr(parent_invocation, attr, value) - with self.telemetry_handler.llm() as child_invocation: - for attr, value in { - "request_model": "child-model", - "input_messages": [message], - "provider": "test-provider", - }.items(): - setattr(child_invocation, attr, value) + with self.telemetry_handler.inference( + "test-provider", request_model="parent-model" + ) as parent_invocation: + parent_invocation.input_messages = [message] + with self.telemetry_handler.inference( + "test-provider", request_model="child-model" + ) as child_invocation: + child_invocation.input_messages = [message] # Stop child first by exiting inner context child_invocation.output_messages = [chat_generation] # Then stop parent by exiting outer context @@ -527,23 +499,18 @@ def test_parent_child_span_relationship(self): emit_event="", ) def test_embedding_parent_child_span_relationship(self): - parent_invocation = EmbeddingInvocation( - request_model="embed-parent-model", - provider="test-provider", - input_tokens=10, - ) - child_invocation = EmbeddingInvocation( - request_model="embed-child-model", - provider="test-provider", - input_tokens=5, + parent_invocation = self.telemetry_handler.start_embedding( + "test-provider", request_model="embed-parent-model" ) - - self.telemetry_handler.start(parent_invocation) + parent_invocation.input_tokens = 10 assert parent_invocation.span is not None - self.telemetry_handler.start(child_invocation) + child_invocation = self.telemetry_handler.start_embedding( + "test-provider", request_model="embed-child-model" + ) + child_invocation.input_tokens = 5 assert child_invocation.span is not None - self.telemetry_handler.stop(child_invocation) - self.telemetry_handler.stop(parent_invocation) + child_invocation.stop() + parent_invocation.stop() spans = self.span_exporter.get_finished_spans() assert len(spans) == 2 @@ -567,22 +534,17 @@ def test_embedding_parent_child_span_relationship(self): def test_llm_parent_embedding_child_span_relationship(self): message = _create_input_message("hi") chat_generation = _create_output_message("ok") - child_invocation = EmbeddingInvocation( - request_model="embed-child-model", - provider="test-provider", - input_tokens=3, - ) - with self.telemetry_handler.llm() as parent_invocation: - for attr, value in { - "request_model": "parent-model", - "input_messages": [message], - "provider": "test-provider", - }.items(): - setattr(parent_invocation, attr, value) - self.telemetry_handler.start(child_invocation) + with self.telemetry_handler.inference( + "test-provider", request_model="parent-model" + ) as parent_invocation: + parent_invocation.input_messages = [message] + child_invocation = self.telemetry_handler.start_embedding( + "test-provider", request_model="embed-child-model" + ) + child_invocation.input_tokens = 3 assert child_invocation.span is not None - self.telemetry_handler.stop(child_invocation) + child_invocation.stop() parent_invocation.output_messages = [chat_generation] spans = self.span_exporter.get_finished_spans() @@ -604,14 +566,12 @@ class BoomError(RuntimeError): pass message = _create_input_message("hi", role="user") - invocation = LLMInvocation( - request_model="test-model", - input_messages=[message], - provider="test-provider", - ) with self.assertRaises(BoomError): - with self.telemetry_handler.llm(invocation): + with self.telemetry_handler.inference( + "test-provider", request_model="test-model" + ) as invocation: + invocation.input_messages = [message] for attr, value in { "max_tokens": 128, "seed": 123, @@ -651,18 +611,16 @@ def test_embedding_context_manager_error_path_records_error_status_and_attrs( class BoomError(RuntimeError): pass - invocation = EmbeddingInvocation( - request_model="embed-model", - provider="test-provider", - dimension_count=1536, - input_tokens=7, - server_address="embed.example.com", - server_port=443, - attributes={"custom_embed_attr": "value"}, - ) - with self.assertRaises(BoomError): - with self.telemetry_handler.embedding(invocation): + with self.telemetry_handler.embedding( + "test-provider", + request_model="embed-model", + server_address="embed.example.com", + server_port=443, + ) as invocation: + invocation.dimension_count = 1536 + invocation.input_tokens = 7 + invocation.attributes["custom_embed_attr"] = "value" invocation.response_model_name = "embed-response-model" raise BoomError("embedding boom") @@ -692,22 +650,20 @@ class BoomError(RuntimeError): emit_event="", ) def test_embedding_manual_start_and_stop_creates_span(self): - invocation = EmbeddingInvocation( + invocation = self.telemetry_handler.start_embedding( + "test-provider", request_model="embed-model", - provider="test-provider", - dimension_count=1536, - encoding_formats=["float"], - input_tokens=123, server_address="custom.server.com", server_port=42, - attributes={"custom_embed_attr": "value"}, ) - - self.telemetry_handler.start(invocation) + invocation.dimension_count = 1536 + invocation.encoding_formats = ["float"] + invocation.input_tokens = 123 + invocation.attributes["custom_embed_attr"] = "value" assert invocation.span is not None invocation.attributes.update({"extra_embed": "info"}) invocation.metric_attributes = {"should not be on span": "value"} - self.telemetry_handler.stop(invocation) + invocation.stop() span = _get_single_span(self.span_exporter) self.assertEqual(span.name, "embeddings embed-model") @@ -731,6 +687,23 @@ def test_embedding_manual_start_and_stop_creates_span(self): }, ) + def test_fail_with_exception_sets_error_status_and_type(self): + class BoomError(RuntimeError): + pass + + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="test-model" + ) + invocation.fail(BoomError("boom")) + + span = _get_single_span(self.span_exporter) + assert span.status.status_code == StatusCode.ERROR + assert span.status.description == "boom" + assert ( + _get_span_attributes(span)[error_attributes.ERROR_TYPE] + == BoomError.__qualname__ + ) + class AnyNonNone: def __eq__(self, other): diff --git a/util/opentelemetry-util-genai/tests/test_utils_events.py b/util/opentelemetry-util-genai/tests/test_utils_events.py index 20b3300c62c..7febea44c6a 100644 --- a/util/opentelemetry-util-genai/tests/test_utils_events.py +++ b/util/opentelemetry-util-genai/tests/test_utils_events.py @@ -30,7 +30,7 @@ ) from opentelemetry.semconv.attributes import error_attributes from opentelemetry.util.genai.handler import get_telemetry_handler -from opentelemetry.util.genai.types import Error, LLMInvocation +from opentelemetry.util.genai.types import Error from .test_utils import ( _create_input_message, @@ -72,22 +72,19 @@ def tearDown(self): emit_event="true", ) def test_emits_llm_event(self): - invocation = LLMInvocation( - request_model="event-model", - input_messages=[_create_input_message("test query")], - system_instruction=_create_system_instruction(), - provider="test-provider", - temperature=0.7, - max_tokens=100, - response_model_name="response-model", - response_id="event-response-id", - input_tokens=10, - output_tokens=20, + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="event-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [_create_input_message("test query")] + invocation.system_instruction = _create_system_instruction() + invocation.temperature = 0.7 + invocation.max_tokens = 100 + invocation.response_model_name = "response-model" + invocation.response_id = "event-response-id" + invocation.input_tokens = 10 + invocation.output_tokens = 20 invocation.output_messages = [_create_output_message("test response")] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check that event was emitted logs = self.log_exporter.get_finished_logs() @@ -157,16 +154,13 @@ def test_emits_llm_event_and_span(self): chat_generation = _create_output_message("combined response") system_instruction = _create_system_instruction("System prompt here") - invocation = LLMInvocation( - request_model="combined-model", - input_messages=[message], - system_instruction=system_instruction, - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="combined-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] + invocation.system_instruction = system_instruction invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check span was created span = _get_single_span(self.span_exporter) @@ -217,15 +211,12 @@ class TestError(RuntimeError): pass message = _create_input_message("error test") - invocation = LLMInvocation( - request_model="error-model", - input_messages=[message], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="error-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] error = Error(message="Test error occurred", type=TestError) - self.telemetry_handler.fail_llm(invocation, error) + invocation.fail(error) # Check event was emitted logs = self.log_exporter.get_finished_logs() @@ -256,15 +247,12 @@ def test_does_not_emit_llm_event_when_emit_event_false(self): message = _create_input_message("emit false test") chat_generation = _create_output_message("emit false response") - invocation = LLMInvocation( - request_model="emit-false-model", - input_messages=[message], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="emit-false-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check no event was emitted logs = self.log_exporter.get_finished_logs() @@ -277,17 +265,14 @@ def test_does_not_emit_llm_event_when_emit_event_false(self): ) def test_does_not_emit_llm_event_by_default_for_no_content(self): """Test that event is not emitted by default when content_capturing is NO_CONTENT and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="default-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [_create_input_message("default test")] invocation.output_messages = [ _create_output_message("default response") ] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check that no event was emitted (NO_CONTENT defaults to False) logs = self.log_exporter.get_finished_logs() @@ -300,17 +285,14 @@ def test_does_not_emit_llm_event_by_default_for_no_content(self): ) def test_does_not_emit_llm_event_by_default_for_span_only(self): """Test that event is not emitted by default when content_capturing is SPAN_ONLY and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="default-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [_create_input_message("default test")] invocation.output_messages = [ _create_output_message("default response") ] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check that no event was emitted (SPAN_ONLY defaults to False) logs = self.log_exporter.get_finished_logs() @@ -323,17 +305,14 @@ def test_does_not_emit_llm_event_by_default_for_span_only(self): ) def test_emits_llm_event_by_default_for_event_only(self): """Test that event is emitted by default when content_capturing is EVENT_ONLY and OTEL_INSTRUMENTATION_GENAI_EMIT_EVENT is not set.""" - invocation = LLMInvocation( - request_model="default-model", - input_messages=[_create_input_message("default test")], - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="default-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [_create_input_message("default test")] invocation.output_messages = [ _create_output_message("default response") ] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check that event was emitted (EVENT_ONLY defaults to True) logs = self.log_exporter.get_finished_logs() @@ -354,16 +333,13 @@ def test_emits_llm_event_by_default_for_span_and_event(self): chat_generation = _create_output_message("span and event response") system_instruction = _create_system_instruction("System prompt") - invocation = LLMInvocation( - request_model="span-and-event-model", - input_messages=[message], - system_instruction=system_instruction, - provider="test-provider", + invocation = self.telemetry_handler.start_inference( + "test-provider", request_model="span-and-event-model" ) - - self.telemetry_handler.start_llm(invocation) + invocation.input_messages = [message] + invocation.system_instruction = system_instruction invocation.output_messages = [chat_generation] - self.telemetry_handler.stop_llm(invocation) + invocation.stop() # Check span was created span = _get_single_span(self.span_exporter) diff --git a/util/opentelemetry-util-genai/tests/test_workflow_invocation.py b/util/opentelemetry-util-genai/tests/test_workflow_invocation.py index b9c0e756dac..3a80f1c214a 100644 --- a/util/opentelemetry-util-genai/tests/test_workflow_invocation.py +++ b/util/opentelemetry-util-genai/tests/test_workflow_invocation.py @@ -1,29 +1,50 @@ +import unittest + +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) +from opentelemetry.trace import INVALID_SPAN +from opentelemetry.util.genai.handler import TelemetryHandler from opentelemetry.util.genai.types import ( InputMessage, OutputMessage, Text, - WorkflowInvocation, ) -class TestWorkflowInvocation: # pylint: disable=no-self-use +class TestWorkflowInvocation(unittest.TestCase): + def setUp(self): + self.span_exporter = InMemorySpanExporter() + tracer_provider = TracerProvider() + tracer_provider.add_span_processor( + SimpleSpanProcessor(self.span_exporter) + ) + self.handler = TelemetryHandler(tracer_provider=tracer_provider) + def test_default_values(self): - invocation = WorkflowInvocation() - assert invocation.name == "" - assert invocation.operation_name == "invoke_workflow" + invocation = self.handler.start_workflow(name=None) + invocation.stop() + assert invocation.name is None + assert invocation._operation_name == "invoke_workflow" assert not invocation.input_messages assert not invocation.output_messages - assert invocation.span is None - assert invocation.context_token is None + assert invocation.span is not INVALID_SPAN assert not invocation.attributes def test_custom_name(self): - invocation = WorkflowInvocation(name="customer_support_pipeline") + invocation = self.handler.start_workflow( + name="customer_support_pipeline" + ) + invocation.stop() assert invocation.name == "customer_support_pipeline" def test_with_input_messages(self): msg = InputMessage(role="user", parts=[Text(content="hello")]) - invocation = WorkflowInvocation(input_messages=[msg]) + invocation = self.handler.start_workflow(name="test") + invocation.input_messages = [msg] + invocation.stop() assert len(invocation.input_messages) == 1 assert invocation.input_messages[0].role == "user" @@ -31,26 +52,36 @@ def test_with_output_messages(self): msg = OutputMessage( role="assistant", parts=[Text(content="hi")], finish_reason="stop" ) - invocation = WorkflowInvocation(output_messages=[msg]) + invocation = self.handler.start_workflow(name="test") + invocation.output_messages = [msg] + invocation.stop() assert len(invocation.output_messages) == 1 assert invocation.output_messages[0].finish_reason == "stop" def test_inherits_genai_invocation(self): - invocation = WorkflowInvocation(attributes={"key": "value"}) - assert invocation.attributes == {"key": "value"} + invocation = self.handler.start_workflow(name="test") + invocation.attributes["key"] = "value" + invocation.stop() + spans = self.span_exporter.get_finished_spans() + assert spans[0].attributes is not None + assert spans[0].attributes["key"] == "value" def test_default_lists_are_independent(self): - """Ensure default factory creates separate list instances.""" - inv1 = WorkflowInvocation() - inv2 = WorkflowInvocation() + """Ensure separate invocations get separate list instances.""" + inv1 = self.handler.start_workflow(name=None) + inv2 = self.handler.start_workflow(name=None) inv1.input_messages.append(InputMessage(role="user", parts=[])) assert len(inv2.input_messages) == 0 + inv1.stop() + inv2.stop() def test_default_attributes_are_independent(self): - inv1 = WorkflowInvocation() - inv2 = WorkflowInvocation() + inv1 = self.handler.start_workflow(name=None) + inv2 = self.handler.start_workflow(name=None) inv1.attributes["foo"] = "bar" assert "foo" not in inv2.attributes + inv1.stop() + inv2.stop() def test_full_construction(self): inp = InputMessage(role="user", parts=[Text(content="query")]) @@ -59,12 +90,10 @@ def test_full_construction(self): parts=[Text(content="answer")], finish_reason="stop", ) - invocation = WorkflowInvocation( - name="my_workflow", - operation_name="invoke_workflow", - input_messages=[inp], - output_messages=[out], - ) + invocation = self.handler.start_workflow(name="my_workflow") + invocation.input_messages = [inp] + invocation.output_messages = [out] + invocation.stop() assert invocation.name == "my_workflow" assert len(invocation.input_messages) == 1 assert len(invocation.output_messages) == 1 From 61b263d7d2dc5c1b04502fbd478df27bb0b535ca Mon Sep 17 00:00:00 2001 From: shuningc Date: Wed, 15 Apr 2026 23:25:08 -0700 Subject: [PATCH 75/78] Adding metrics call for Embedding type after refactoring --- .../src/opentelemetry/util/genai/_embedding_invocation.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py index e7fa59b6000..c4a2f2f4277 100644 --- a/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py +++ b/util/opentelemetry-util-genai/src/opentelemetry/util/genai/_embedding_invocation.py @@ -120,5 +120,4 @@ def _apply_finish(self, error: Error | None = None) -> None: self._apply_error_attributes(error) attributes.update(self.attributes) self.span.set_attributes(attributes) - # Metrics recorder currently supports InferenceInvocation fields only. - # No-op until dedicated embedding metric support is added. + self._metrics_recorder.record(self) From 5cc6e65b37a725540fb1fa6c7f9697e2b4ff29e9 Mon Sep 17 00:00:00 2001 From: shuningc Date: Wed, 15 Apr 2026 23:46:51 -0700 Subject: [PATCH 76/78] Updating metrics tests with embedding --- .../tests/test_handler_metrics.py | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/util/opentelemetry-util-genai/tests/test_handler_metrics.py b/util/opentelemetry-util-genai/tests/test_handler_metrics.py index b28ed96bf50..233edb90505 100644 --- a/util/opentelemetry-util-genai/tests/test_handler_metrics.py +++ b/util/opentelemetry-util-genai/tests/test_handler_metrics.py @@ -188,17 +188,16 @@ def test_stop_embedding_records_duration_and_tokens(self) -> None: tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, ) - invocation = EmbeddingInvocation( - request_model="embed-model", provider="embed-prov" - ) - invocation.input_tokens = 100 # Patch default_timer during start to ensure monotonic_start_s with patch("timeit.default_timer", return_value=1000.0): - handler.start(invocation) + invocation = handler.start_embedding( + "embed-prov", request_model="embed-model" + ) + invocation.input_tokens = 100 # Simulate 1.5 seconds of elapsed monotonic time with patch("timeit.default_timer", return_value=1001.5): - handler.stop(invocation) + invocation.stop() self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -240,16 +239,15 @@ def test_stop_embedding_records_duration_with_additional_attributes( tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, ) - invocation = EmbeddingInvocation( + invocation = handler.start_embedding( + "embed-prov", request_model="embed-model", - provider="embed-prov", server_address="embed.server.com", server_port=8080, ) - handler.start(invocation) invocation.metric_attributes = {"custom.embed.attr": "embed_value"} invocation.response_model_name = "embed-response-model" - handler.stop(invocation) + invocation.stop() self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -277,15 +275,14 @@ def test_fail_embedding_records_error_and_duration(self) -> None: tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, ) - invocation = EmbeddingInvocation( - request_model="embed-err-model", provider="embed-prov" - ) with patch("timeit.default_timer", return_value=3000.0): - handler.start(invocation) + invocation = handler.start_embedding( + "embed-prov", request_model="embed-err-model" + ) error = Error(message="embedding failed", type=RuntimeError) with patch("timeit.default_timer", return_value=3002.5): - handler.fail(invocation, error) + invocation.fail(error) self._assert_metric_scope_schema_urls(_DEFAULT_SCHEMA_URL) metrics = self._harvest_metrics() @@ -313,12 +310,11 @@ def test_stop_embedding_without_tokens(self) -> None: tracer_provider=self.tracer_provider, meter_provider=self.meter_provider, ) - invocation = EmbeddingInvocation( - request_model="embed-model", provider="embed-prov" + invocation = handler.start_embedding( + "embed-prov", request_model="embed-model" ) # input_tokens is not set - handler.start(invocation) - handler.stop(invocation) + invocation.stop() metrics = self._harvest_metrics() From 498b92850140e59e041edbb214ad8ace978888e5 Mon Sep 17 00:00:00 2001 From: Vivek Bharath Akupatni Date: Thu, 16 Apr 2026 11:07:04 -0400 Subject: [PATCH 77/78] maint: Add ci workflow to check links (#4432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add ci workflow to check links * Address code review * Add rst files as well * Apply suggestion from @emdneto --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> --- .github/workflows/check-links.yml | 52 +++++++++++++++++++++++ .github/workflows/check_links_config.json | 14 ++++++ 2 files changed, 66 insertions(+) create mode 100644 .github/workflows/check-links.yml create mode 100644 .github/workflows/check_links_config.json diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml new file mode 100644 index 00000000000..4a5b47acfe0 --- /dev/null +++ b/.github/workflows/check-links.yml @@ -0,0 +1,52 @@ +name: check-links +on: + push: + branches: [ main ] + paths: + - '**/*.md' + - '**/*.rst' + - '.github/workflows/check-links.yml' + - '.github/workflows/check_links_config.json' + pull_request: + paths: + - '**/*.md' + - '**/*.rst' + - '.github/workflows/check-links.yml' + - '.github/workflows/check_links_config.json' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: true + +jobs: + check-links: + runs-on: ubuntu-latest + if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'otelbot[bot]' }} + timeout-minutes: 15 + steps: + - name: Checkout Repo + uses: actions/checkout@v6 + + - name: Get changed markdown files + id: changed-files + uses: tj-actions/changed-files@v46 + with: + files: | + **/*.md + **/*.rst + + - name: Install markdown-link-check + if: steps.changed-files.outputs.any_changed == 'true' + run: npm install -g markdown-link-check@v3.12.2 + + - name: Run markdown-link-check + if: steps.changed-files.outputs.any_changed == 'true' + run: | + markdown-link-check \ + --verbose \ + --config .github/workflows/check_links_config.json \ + ${{ steps.changed-files.outputs.all_changed_files }} \ + || { echo "Check that anchor links are lowercase"; exit 1; } diff --git a/.github/workflows/check_links_config.json b/.github/workflows/check_links_config.json new file mode 100644 index 00000000000..57f555a0034 --- /dev/null +++ b/.github/workflows/check_links_config.json @@ -0,0 +1,14 @@ +{ + "ignorePatterns": [ + { + "pattern": "http(s)?://\\d+\\.\\d+\\.\\d+\\.\\d+" + }, + { + "pattern": "http(s)?://localhost" + }, + { + "pattern": "http(s)?://example.com" + } + ], + "aliveStatusCodes": [429, 200] +} From 1af0a2a72ed2e9e16c95181269a192269044f285 Mon Sep 17 00:00:00 2001 From: shuningc Date: Thu, 16 Apr 2026 13:02:06 -0700 Subject: [PATCH 78/78] Adding fix for markdown-link-check --- util/opentelemetry-util-genai/CHANGELOG.md | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/util/opentelemetry-util-genai/CHANGELOG.md b/util/opentelemetry-util-genai/CHANGELOG.md index 3b8f0b1d8cc..1ddd22cee8c 100644 --- a/util/opentelemetry-util-genai/CHANGELOG.md +++ b/util/opentelemetry-util-genai/CHANGELOG.md @@ -10,17 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add metrics support for EmbeddingInvocation ([#4377](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4377)) - Add support for workflow in genAI utils handler. - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4366](#4366)) + ([#4366](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4366)) - Enrich ToolCall type, breaking change: usage of ToolCall class renamed to ToolCallRequest ([#4218](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4218)) - Add EmbeddingInvocation span lifecycle support - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4219](#4219)) + ([#4219](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4219)) - Populate schema_url on metrics ([#4320](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4320)) - Add workflow invocation type to genAI utils - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4310](#4310)) + ([#4310](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4310)) - Check if upload works at startup in initializer of the `UploadCompletionHook`, instead -of repeatedly failing on every upload ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4390](#4390)). +of repeatedly failing on every upload ([#4390](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4390)). - Refactor public API: add factory methods (`start_inference`, `start_embedding`, `start_tool`, `start_workflow`) and invocation-owned lifecycle (`invocation.stop()` / `invocation.fail(exc)`); rename `LLMInvocation` → `InferenceInvocation` and `ToolCall` → `ToolInvocation`. Existing usages remain fully functional via deprecated aliases. ([#4391](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4391)) @@ -34,28 +34,28 @@ of repeatedly failing on every upload ([https://github.com/open-telemetry/opente - Log error when `fsspec` fails to be imported instead of silently failing ([#4037](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4037)). - Minor change to check LRU cache in Completion Hook before acquiring semaphore/thread ([#3907](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3907)). - Add environment variable for genai upload hook queue size - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3943](#3943)) + ([#3943](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3943)) - Add more Semconv attributes to LLMInvocation spans. - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3862](#3862)) + ([#3862](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3862)) - Limit the upload hook thread pool to 64 workers - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3944](#3944)) + ([#3944](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3944)) - Add metrics to LLMInvocation traces - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3891](#3891)) + ([#3891](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3891)) - Add parent class genAI invocation - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3889](#3889)) + ([#3889](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3889)) ## Version 0.2b0 (2025-10-14) - Add jsonlines support to fsspec uploader - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3791](#3791)) + ([#3791](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3791)) - Rename "fsspec_upload" entry point and classes to more generic "upload" - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3798](#3798)) + ([#3798](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3798)) - Record content-type and use canonical paths in fsspec genai uploader - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3795](#3795)) + ([#3795](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3795)) - Make inputs / outputs / system instructions optional params to `on_completion`, - ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3802](#3802)). + ([#3802](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3802)). - Use a SHA256 hash of the system instructions as it's upload filename, and check - if the file exists before re-uploading it, ([https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3814](#3814)). + if the file exists before re-uploading it, ([#3814](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3814)). ## Version 0.1b0 (2025-09-25)