Add asyncclick instrumentation (#3319)
* Add asyncclick instrumentation * Add instrumentation for asyncclick based CLI apps * Add tox * Add Changelog * Update workflows This implementation is based on the original click instrumentation work by: - Emídio Neto <9735060+emdneto@users.noreply.github.com> - Anuraag (Rag) Agrawal <anuraaga@gmail.com> - Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com> * Update CHANGELOG.md Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> * Fix async refs in code-block example --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									50ab047143
								
							
						
					
					
						commit
						0ea9998c4c
					
				|  | @ -11,6 +11,9 @@ components: | |||
|     - oxeye-nikolay | ||||
|     - nikosokolik | ||||
|    | ||||
|   instrumentation/opentelemetry-instrumentation-asyncclick: | ||||
|     - jomcgi | ||||
| 
 | ||||
|   instrumentation/opentelemetry-instrumentation-kafka-python: | ||||
|     - nozik | ||||
|    | ||||
|  |  | |||
|  | @ -525,6 +525,28 @@ jobs: | |||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-boto -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-asyncclick: | ||||
|     name: instrumentation-asyncclick  | ||||
|     runs-on: ubuntu-latest | ||||
|     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: Set up Python 3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.8" | ||||
|           architecture: "x64" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-asyncclick -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-click: | ||||
|     name: instrumentation-click  | ||||
|     runs-on: ubuntu-latest | ||||
|  |  | |||
|  | @ -322,6 +322,24 @@ jobs: | |||
|       - name: Run tests | ||||
|         run: tox -e lint-instrumentation-boto | ||||
| 
 | ||||
|   lint-instrumentation-asyncclick: | ||||
|     name: instrumentation-asyncclick | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.13 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.13" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e lint-instrumentation-asyncclick | ||||
| 
 | ||||
|   lint-instrumentation-click: | ||||
|     name: instrumentation-click | ||||
|     runs-on: ubuntu-latest | ||||
|  |  | |||
|  | @ -2842,6 +2842,132 @@ jobs: | |||
|       - name: Run tests | ||||
|         run: tox -e py311-test-instrumentation-boto -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-asyncclick_ubuntu-latest: | ||||
|     name: instrumentation-asyncclick 3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-asyncclick -- -ra | ||||
| 
 | ||||
|   py39-test-instrumentation-asyncclick_ubuntu-latest: | ||||
|     name: instrumentation-asyncclick 3.9 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.9 | ||||
|         uses: actions/setup-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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.10 | ||||
|         uses: actions/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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.11 | ||||
|         uses: actions/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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.12 | ||||
|         uses: actions/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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.13 | ||||
|         uses: actions/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 | ||||
| 
 | ||||
|   pypy3-test-instrumentation-asyncclick_ubuntu-latest: | ||||
|     name: instrumentation-asyncclick pypy-3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python pypy-3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "pypy-3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e pypy3-test-instrumentation-asyncclick -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-click_ubuntu-latest: | ||||
|     name: instrumentation-click 3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|  | @ -4389,129 +4515,3 @@ jobs: | |||
| 
 | ||||
|       - 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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.13 | ||||
|         uses: actions/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 | ||||
| 
 | ||||
|   pypy3-test-instrumentation-urllib_ubuntu-latest: | ||||
|     name: instrumentation-urllib pypy-3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python pypy-3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "pypy-3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e pypy3-test-instrumentation-urllib -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-urllib3-0_ubuntu-latest: | ||||
|     name: instrumentation-urllib3-0 3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-urllib3-0 -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-urllib3-1_ubuntu-latest: | ||||
|     name: instrumentation-urllib3-1 3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-urllib3-1 -- -ra | ||||
| 
 | ||||
|   py39-test-instrumentation-urllib3-0_ubuntu-latest: | ||||
|     name: instrumentation-urllib3-0 3.9 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.9 | ||||
|         uses: actions/setup-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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.9 | ||||
|         uses: actions/setup-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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.10 | ||||
|         uses: actions/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 | ||||
|  |  | |||
|  | @ -16,6 +16,132 @@ env: | |||
| 
 | ||||
| jobs: | ||||
| 
 | ||||
|   py313-test-instrumentation-urllib_ubuntu-latest: | ||||
|     name: instrumentation-urllib 3.13 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.13 | ||||
|         uses: actions/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 | ||||
| 
 | ||||
|   pypy3-test-instrumentation-urllib_ubuntu-latest: | ||||
|     name: instrumentation-urllib pypy-3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python pypy-3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "pypy-3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e pypy3-test-instrumentation-urllib -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-urllib3-0_ubuntu-latest: | ||||
|     name: instrumentation-urllib3-0 3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-urllib3-0 -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-urllib3-1_ubuntu-latest: | ||||
|     name: instrumentation-urllib3-1 3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-urllib3-1 -- -ra | ||||
| 
 | ||||
|   py39-test-instrumentation-urllib3-0_ubuntu-latest: | ||||
|     name: instrumentation-urllib3-0 3.9 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.9 | ||||
|         uses: actions/setup-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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.9 | ||||
|         uses: actions/setup-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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.10 | ||||
|         uses: actions/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 | ||||
|  | @ -4389,129 +4515,3 @@ jobs: | |||
| 
 | ||||
|       - 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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.13 | ||||
|         uses: actions/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 | ||||
| 
 | ||||
|   pypy3-test-instrumentation-threading_ubuntu-latest: | ||||
|     name: instrumentation-threading pypy-3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python pypy-3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "pypy-3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e pypy3-test-instrumentation-threading -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-tornado_ubuntu-latest: | ||||
|     name: instrumentation-tornado 3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-tornado -- -ra | ||||
| 
 | ||||
|   py39-test-instrumentation-tornado_ubuntu-latest: | ||||
|     name: instrumentation-tornado 3.9 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.9 | ||||
|         uses: actions/setup-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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.10 | ||||
|         uses: actions/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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.11 | ||||
|         uses: actions/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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.12 | ||||
|         uses: actions/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 | ||||
|  |  | |||
|  | @ -16,6 +16,132 @@ env: | |||
| 
 | ||||
| jobs: | ||||
| 
 | ||||
|   py313-test-instrumentation-threading_ubuntu-latest: | ||||
|     name: instrumentation-threading 3.13 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.13 | ||||
|         uses: actions/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 | ||||
| 
 | ||||
|   pypy3-test-instrumentation-threading_ubuntu-latest: | ||||
|     name: instrumentation-threading pypy-3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python pypy-3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "pypy-3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e pypy3-test-instrumentation-threading -- -ra | ||||
| 
 | ||||
|   py38-test-instrumentation-tornado_ubuntu-latest: | ||||
|     name: instrumentation-tornado 3.8 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.8 | ||||
|         uses: actions/setup-python@v5 | ||||
|         with: | ||||
|           python-version: "3.8" | ||||
| 
 | ||||
|       - name: Install tox | ||||
|         run: pip install tox-uv | ||||
| 
 | ||||
|       - name: Run tests | ||||
|         run: tox -e py38-test-instrumentation-tornado -- -ra | ||||
| 
 | ||||
|   py39-test-instrumentation-tornado_ubuntu-latest: | ||||
|     name: instrumentation-tornado 3.9 Ubuntu | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.9 | ||||
|         uses: actions/setup-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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.10 | ||||
|         uses: actions/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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.11 | ||||
|         uses: actions/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 | ||||
|     steps: | ||||
|       - name: Checkout repo @ SHA - ${{ github.sha }} | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Set up Python 3.12 | ||||
|         uses: actions/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 | ||||
|  |  | |||
|  | @ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 
 | ||||
| ## Unreleased | ||||
| 
 | ||||
| - `opentelemetry-instrumentation-asyncclick`: new instrumentation to trace asyncclick commands | ||||
|   ([#3319](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3319)) | ||||
| 
 | ||||
| ### Fixed | ||||
| 
 | ||||
| - `opentelemetry-instrumentation` Fix client address is set to server address in new semconv | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ aiohttp~=3.0 | |||
| 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 | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| .. include:: ../../../instrumentation/opentelemetry-instrumentation-asyncclick/README.rst | ||||
|     :end-before: References | ||||
| 
 | ||||
| .. automodule:: opentelemetry.instrumentation.asyncclick | ||||
|     :members: | ||||
|     :undoc-members: | ||||
|     :show-inheritance: | ||||
|  | @ -7,6 +7,7 @@ | |||
| | [opentelemetry-instrumentation-aiokafka](./opentelemetry-instrumentation-aiokafka) | aiokafka >= 0.8, < 1.0 | No | development | ||||
| | [opentelemetry-instrumentation-aiopg](./opentelemetry-instrumentation-aiopg) | aiopg >= 0.13.0, < 2.0.0 | No | development | ||||
| | [opentelemetry-instrumentation-asgi](./opentelemetry-instrumentation-asgi) | asgiref ~= 3.0 | Yes | migration | ||||
| | [opentelemetry-instrumentation-asyncclick](./opentelemetry-instrumentation-asyncclick) | asyncclick ~= 8.0 | No | development | ||||
| | [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 | ||||
|  |  | |||
|  | @ -0,0 +1,24 @@ | |||
| OpenTelemetry asyncclick Instrumentation | ||||
| ======================================== | ||||
| 
 | ||||
| |pypi| | ||||
| 
 | ||||
| .. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-asyncclick.svg | ||||
|    :target: https://pypi.org/project/opentelemetry-instrumentation-asyncclick/ | ||||
| 
 | ||||
| This library allows tracing requests made by the asyncclick fork of the click library. | ||||
| 
 | ||||
| Installation | ||||
| ------------ | ||||
| 
 | ||||
| 
 | ||||
| :: | ||||
| 
 | ||||
|     pip install opentelemetry-instrumentation-asyncclick | ||||
| 
 | ||||
| 
 | ||||
| References | ||||
| ---------- | ||||
| 
 | ||||
| * `OpenTelemetry asyncclick/ Tracing <https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/asyncclick/asyncclick.html>`_ | ||||
| * `OpenTelemetry Project <https://opentelemetry.io/>`_ | ||||
|  | @ -0,0 +1,57 @@ | |||
| [build-system] | ||||
| requires = ["hatchling"] | ||||
| build-backend = "hatchling.build" | ||||
| 
 | ||||
| [project] | ||||
| name = "opentelemetry-instrumentation-asyncclick" | ||||
| dynamic = ["version"] | ||||
| description = "Async Click instrumentation for OpenTelemetry" | ||||
| readme = "README.rst" | ||||
| license = "Apache-2.0" | ||||
| requires-python = ">=3.8" | ||||
| 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.8", | ||||
|   "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", | ||||
|   "opentelemetry-semantic-conventions == 0.53b0.dev", | ||||
|   "wrapt ~= 1.0", | ||||
|   "typing_extensions ~= 4.12", | ||||
| ] | ||||
| 
 | ||||
| [project.optional-dependencies] | ||||
| instruments = [ | ||||
|   "asyncclick ~= 8.0", | ||||
| ] | ||||
| 
 | ||||
| [project.entry-points.opentelemetry_instrumentor] | ||||
| asyncclick = "opentelemetry.instrumentation.asyncclick:AsyncClickInstrumentor" | ||||
| 
 | ||||
| [project.urls] | ||||
| Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentation-asyncclick" | ||||
| Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" | ||||
| 
 | ||||
| [tool.hatch.version] | ||||
| path = "src/opentelemetry/instrumentation/asyncclick/version.py" | ||||
| 
 | ||||
| [tool.hatch.build.targets.sdist] | ||||
| include = [ | ||||
|   "/src", | ||||
|   "/tests", | ||||
| ] | ||||
| 
 | ||||
| [tool.hatch.build.targets.wheel] | ||||
| packages = ["src/opentelemetry"] | ||||
|  | @ -0,0 +1,163 @@ | |||
| # 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 `asyncclick`_ CLI applications. The instrumentor will avoid instrumenting | ||||
| well-known servers (e.g. *flask run* and *uvicorn*) to avoid unexpected effects | ||||
| like every request having the same Trace ID. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| .. _asyncclick: https://pypi.org/project/asyncclick/ | ||||
| 
 | ||||
| Usage | ||||
| ----- | ||||
| 
 | ||||
| .. code-block:: python | ||||
| 
 | ||||
|     import asyncio | ||||
|     import asyncclick | ||||
|     from opentelemetry.instrumentation.asyncclick import AsyncClickInstrumentor | ||||
| 
 | ||||
|     AsyncClickInstrumentor().instrument() | ||||
| 
 | ||||
|     @asyncclick.command() | ||||
|     async def hello(): | ||||
|         asyncclick.echo(f'Hello world!') | ||||
| 
 | ||||
|     if __name__ == "__main__": | ||||
|         asyncio.run(hello()) | ||||
| 
 | ||||
| API | ||||
| --- | ||||
| """ | ||||
| 
 | ||||
| from __future__ import annotations | ||||
| 
 | ||||
| import os | ||||
| import sys | ||||
| from functools import partial | ||||
| from logging import getLogger | ||||
| from typing import ( | ||||
|     TYPE_CHECKING, | ||||
|     Any, | ||||
|     Awaitable, | ||||
|     Callable, | ||||
|     Collection, | ||||
|     TypeVar, | ||||
| ) | ||||
| 
 | ||||
| import asyncclick | ||||
| from typing_extensions import ParamSpec, Unpack | ||||
| from wrapt import ( | ||||
|     wrap_function_wrapper,  # type: ignore[reportUnknownVariableType] | ||||
| ) | ||||
| 
 | ||||
| from opentelemetry import trace | ||||
| from opentelemetry.instrumentation.asyncclick.package import _instruments | ||||
| from opentelemetry.instrumentation.asyncclick.version import __version__ | ||||
| from opentelemetry.instrumentation.instrumentor import BaseInstrumentor | ||||
| from opentelemetry.instrumentation.utils import ( | ||||
|     unwrap, | ||||
| ) | ||||
| from opentelemetry.semconv._incubating.attributes.process_attributes import ( | ||||
|     PROCESS_COMMAND_ARGS, | ||||
|     PROCESS_EXECUTABLE_NAME, | ||||
|     PROCESS_EXIT_CODE, | ||||
|     PROCESS_PID, | ||||
| ) | ||||
| from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE | ||||
| from opentelemetry.trace.status import StatusCode | ||||
| 
 | ||||
| if TYPE_CHECKING: | ||||
|     from typing import TypedDict | ||||
| 
 | ||||
|     class InstrumentKwargs(TypedDict, total=False): | ||||
|         tracer_provider: trace.TracerProvider | ||||
| 
 | ||||
|     class UninstrumentKwargs(TypedDict, total=False): | ||||
|         pass | ||||
| 
 | ||||
| 
 | ||||
| _logger = getLogger(__name__) | ||||
| 
 | ||||
| 
 | ||||
| T = TypeVar("T") | ||||
| P = ParamSpec("P") | ||||
| 
 | ||||
| 
 | ||||
| async def _command_invoke_wrapper( | ||||
|     wrapped: Callable[P, Awaitable[T]], | ||||
|     instance: asyncclick.core.Command, | ||||
|     args: tuple[Any, ...], | ||||
|     kwargs: dict[str, Any], | ||||
|     tracer: trace.Tracer, | ||||
| ) -> T: | ||||
|     # Subclasses of Command include groups and CLI runners, but | ||||
|     # we only want to instrument the actual commands which are | ||||
|     # instances of Command itself. | ||||
|     if instance.__class__ != asyncclick.Command: | ||||
|         return await wrapped(*args, **kwargs) | ||||
| 
 | ||||
|     ctx = args[0] | ||||
| 
 | ||||
|     span_name = ctx.info_name | ||||
|     span_attributes = { | ||||
|         PROCESS_COMMAND_ARGS: sys.argv, | ||||
|         PROCESS_EXECUTABLE_NAME: sys.argv[0], | ||||
|         PROCESS_EXIT_CODE: 0, | ||||
|         PROCESS_PID: os.getpid(), | ||||
|     } | ||||
| 
 | ||||
|     with tracer.start_as_current_span( | ||||
|         name=span_name, | ||||
|         kind=trace.SpanKind.INTERNAL, | ||||
|         attributes=span_attributes, | ||||
|     ) as span: | ||||
|         try: | ||||
|             result = await wrapped(*args, **kwargs) | ||||
|             return result | ||||
|         except Exception as exc: | ||||
|             span.set_status(StatusCode.ERROR, str(exc)) | ||||
|             if span.is_recording(): | ||||
|                 span.set_attribute(ERROR_TYPE, type(exc).__qualname__) | ||||
|                 span.set_attribute( | ||||
|                     PROCESS_EXIT_CODE, getattr(exc, "exit_code", 1) | ||||
|                 ) | ||||
|             raise | ||||
| 
 | ||||
| 
 | ||||
| # pylint: disable=no-self-use | ||||
| class AsyncClickInstrumentor(BaseInstrumentor): | ||||
|     """An instrumentor for asyncclick""" | ||||
| 
 | ||||
|     def instrumentation_dependencies(self) -> Collection[str]: | ||||
|         return _instruments | ||||
| 
 | ||||
|     def _instrument(self, **kwargs: Unpack[InstrumentKwargs]) -> None: | ||||
|         tracer_provider = kwargs.get("tracer_provider") | ||||
|         tracer = trace.get_tracer( | ||||
|             __name__, | ||||
|             __version__, | ||||
|             tracer_provider, | ||||
|         ) | ||||
| 
 | ||||
|         wrap_function_wrapper( | ||||
|             asyncclick.core.Command, | ||||
|             "invoke", | ||||
|             partial(_command_invoke_wrapper, tracer=tracer), | ||||
|         ) | ||||
| 
 | ||||
|     def _uninstrument(self, **kwargs: Unpack["UninstrumentKwargs"]) -> None: | ||||
|         unwrap(asyncclick.core.Command, "invoke") | ||||
|  | @ -0,0 +1,16 @@ | |||
| # 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 = ("asyncclick ~= 8.0",) | ||||
|  | @ -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.53b0.dev" | ||||
|  | @ -0,0 +1,10 @@ | |||
| 
 | ||||
| asyncclick~=8.0 | ||||
| Flask~=3.0 | ||||
| pytest==7.4.4 | ||||
| anyio~=4.5 | ||||
| -e opentelemetry-instrumentation | ||||
| -e instrumentation/opentelemetry-instrumentation-asyncclick | ||||
| -e instrumentation/opentelemetry-instrumentation-flask | ||||
| -e instrumentation/opentelemetry-instrumentation-wsgi | ||||
| -e util/opentelemetry-util-http | ||||
|  | @ -0,0 +1,371 @@ | |||
| # 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 asyncio | ||||
| import os | ||||
| from typing import Any | ||||
| from unittest import IsolatedAsyncioTestCase, mock | ||||
| 
 | ||||
| import asyncclick | ||||
| import asyncclick.testing | ||||
| from asyncclick.testing import CliRunner | ||||
| 
 | ||||
| from opentelemetry.instrumentation.asyncclick import AsyncClickInstrumentor | ||||
| from opentelemetry.test.test_base import TestBase | ||||
| from opentelemetry.trace import SpanKind | ||||
| from opentelemetry.trace.status import StatusCode | ||||
| 
 | ||||
| 
 | ||||
| def run_asyncclick_command_test( | ||||
|     command: asyncclick.core.Command, args: tuple[Any, ...] = (), **kwargs: Any | ||||
| ) -> asyncclick.testing.Result: | ||||
|     """ | ||||
|     Run an asyncclick command and return the result. | ||||
| 
 | ||||
|     Args: | ||||
|         command: The AsyncClick command to run | ||||
|         args: Command-line arguments | ||||
|         **kwargs: Additional arguments for CliRunner.invoke | ||||
| 
 | ||||
|     Returns: | ||||
|         The result of invoking the command | ||||
|     """ | ||||
| 
 | ||||
|     async def _run() -> asyncclick.testing.Result: | ||||
|         runner = CliRunner() | ||||
|         return await runner.invoke(command, args, **kwargs) | ||||
| 
 | ||||
|     return asyncio.run(_run()) | ||||
| 
 | ||||
| 
 | ||||
| class ClickTestCase(TestBase, IsolatedAsyncioTestCase): | ||||
|     # pylint: disable=unbalanced-tuple-unpacking | ||||
|     def setUp(self):  # pylint: disable=invalid-name | ||||
|         super().setUp() | ||||
| 
 | ||||
|         AsyncClickInstrumentor().instrument() | ||||
| 
 | ||||
|     def tearDown(self):  # pylint: disable=invalid-name | ||||
|         super().tearDown() | ||||
|         AsyncClickInstrumentor().uninstrument() | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py"]) | ||||
|     def test_cli_command_wrapping(self): | ||||
|         @asyncclick.command() | ||||
|         async def command() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(command) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
| 
 | ||||
|         (span,) = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(span.status.status_code, StatusCode.UNSET) | ||||
|         self.assertEqual(span.kind, SpanKind.INTERNAL) | ||||
|         self.assertEqual(span.name, "command") | ||||
|         self.assertEqual( | ||||
|             dict(span.attributes), | ||||
|             { | ||||
|                 "process.executable.name": "command.py", | ||||
|                 "process.command_args": ("command.py",), | ||||
|                 "process.exit.code": 0, | ||||
|                 "process.pid": os.getpid(), | ||||
|             }, | ||||
|         ) | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py"]) | ||||
|     def test_cli_command_wrapping_with_name(self): | ||||
|         @asyncclick.command("mycommand") | ||||
|         async def renamedcommand() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(renamedcommand) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
| 
 | ||||
|         (span,) = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(span.status.status_code, StatusCode.UNSET) | ||||
|         self.assertEqual(span.kind, SpanKind.INTERNAL) | ||||
|         self.assertEqual(span.name, "mycommand") | ||||
|         self.assertEqual( | ||||
|             dict(span.attributes), | ||||
|             { | ||||
|                 "process.executable.name": "command.py", | ||||
|                 "process.command_args": ("command.py",), | ||||
|                 "process.exit.code": 0, | ||||
|                 "process.pid": os.getpid(), | ||||
|             }, | ||||
|         ) | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py", "--opt", "argument"]) | ||||
|     def test_cli_command_wrapping_with_options(self): | ||||
|         @asyncclick.command() | ||||
|         @asyncclick.argument("argument") | ||||
|         @asyncclick.option("--opt/--no-opt", default=False) | ||||
|         async def command(argument: str, opt: str) -> None: | ||||
|             pass | ||||
| 
 | ||||
|         argv = ["command.py", "--opt", "argument"] | ||||
|         result = run_asyncclick_command_test(command, argv[1:]) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
| 
 | ||||
|         (span,) = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(span.status.status_code, StatusCode.UNSET) | ||||
|         self.assertEqual(span.kind, SpanKind.INTERNAL) | ||||
|         self.assertEqual(span.name, "command") | ||||
|         self.assertEqual( | ||||
|             dict(span.attributes), | ||||
|             { | ||||
|                 "process.executable.name": "command.py", | ||||
|                 "process.command_args": tuple(argv), | ||||
|                 "process.exit.code": 0, | ||||
|                 "process.pid": os.getpid(), | ||||
|             }, | ||||
|         ) | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command-raises.py"]) | ||||
|     def test_cli_command_raises_error(self): | ||||
|         @asyncclick.command() | ||||
|         async def command_raises() -> None: | ||||
|             raise ValueError() | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(command_raises) | ||||
|         self.assertEqual(result.exit_code, 1) | ||||
| 
 | ||||
|         (span,) = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(span.status.status_code, StatusCode.ERROR) | ||||
|         self.assertEqual(span.kind, SpanKind.INTERNAL) | ||||
|         self.assertEqual(span.name, "command-raises") | ||||
|         self.assertEqual( | ||||
|             dict(span.attributes), | ||||
|             { | ||||
|                 "process.executable.name": "command-raises.py", | ||||
|                 "process.command_args": ("command-raises.py",), | ||||
|                 "process.exit.code": 1, | ||||
|                 "process.pid": os.getpid(), | ||||
|                 "error.type": "ValueError", | ||||
|             }, | ||||
|         ) | ||||
| 
 | ||||
|     def test_uninstrument(self): | ||||
|         AsyncClickInstrumentor().uninstrument() | ||||
| 
 | ||||
|         @asyncclick.command() | ||||
|         async def notracecommand() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(notracecommand) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
| 
 | ||||
|         self.assertFalse(self.memory_exporter.get_finished_spans()) | ||||
|         AsyncClickInstrumentor().instrument() | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py", "sub1", "sub2"]) | ||||
|     def test_nested_command_groups(self): | ||||
|         """Test instrumentation of nested command groups.""" | ||||
| 
 | ||||
|         @asyncclick.group() | ||||
|         async def cli() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         @cli.group() | ||||
|         async def sub1() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         @sub1.command() | ||||
|         async def sub2() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(cli, ["sub1", "sub2"]) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
| 
 | ||||
|         spans = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual( | ||||
|             len(spans), 1 | ||||
|         )  # Only the leaf command should be instrumented | ||||
|         span = spans[0] | ||||
|         self.assertEqual(span.name, "sub2") | ||||
|         self.assertEqual( | ||||
|             dict(span.attributes), | ||||
|             { | ||||
|                 "process.executable.name": "command.py", | ||||
|                 "process.command_args": ("command.py", "sub1", "sub2"), | ||||
|                 "process.exit.code": 0, | ||||
|                 "process.pid": os.getpid(), | ||||
|             }, | ||||
|         ) | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py"]) | ||||
|     def test_command_with_callback(self): | ||||
|         """Test instrumentation of commands with callbacks.""" | ||||
|         callback_called = False | ||||
| 
 | ||||
|         def callback_func( | ||||
|             ctx: asyncclick.Context, param: asyncclick.Parameter, value: bool | ||||
|         ) -> bool: | ||||
|             nonlocal callback_called | ||||
|             callback_called = True | ||||
|             return value | ||||
| 
 | ||||
|         @asyncclick.command() | ||||
|         @asyncclick.option( | ||||
|             "--option", callback=callback_func, default="default" | ||||
|         ) | ||||
|         async def command(option: str) -> None: | ||||
|             pass | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(command) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
|         self.assertTrue(callback_called) | ||||
| 
 | ||||
|         (span,) = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(span.name, "command") | ||||
|         self.assertEqual(span.status.status_code, StatusCode.UNSET) | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py"]) | ||||
|     def test_command_with_result_callback(self): | ||||
|         """Test instrumentation with result callbacks.""" | ||||
|         callback_called = False | ||||
| 
 | ||||
|         @asyncclick.group(chain=True) | ||||
|         async def cli() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         @cli.result_callback() | ||||
|         async def process_result(result: asyncclick.testing.Result) -> None: | ||||
|             nonlocal callback_called | ||||
|             callback_called = True | ||||
| 
 | ||||
|         @cli.command() | ||||
|         async def command() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(cli, ["command"]) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
|         self.assertTrue(callback_called) | ||||
| 
 | ||||
|         spans = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(len(spans), 1) | ||||
|         span = spans[0] | ||||
|         self.assertEqual(span.name, "command") | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py"]) | ||||
|     def test_command_chaining(self): | ||||
|         """Test instrumentation with command chaining.""" | ||||
| 
 | ||||
|         @asyncclick.group(chain=True) | ||||
|         async def cli() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         @cli.command() | ||||
|         async def cmd1() -> None: | ||||
|             return "result1" | ||||
| 
 | ||||
|         @cli.command() | ||||
|         async def cmd2() -> None: | ||||
|             return "result2" | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(cli, ["cmd1", "cmd2"]) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
| 
 | ||||
|         spans = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(len(spans), 2) | ||||
|         # Spans should be ordered by execution | ||||
|         self.assertEqual(spans[0].name, "cmd1") | ||||
|         self.assertEqual(spans[1].name, "cmd2") | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py"]) | ||||
|     def test_custom_exit_codes(self) -> None: | ||||
|         """Test instrumentation with custom exit codes.""" | ||||
| 
 | ||||
|         @asyncclick.command() | ||||
|         async def command() -> None: | ||||
|             raise asyncclick.exceptions.Exit(code=42) | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(command) | ||||
|         self.assertEqual(result.exit_code, 42) | ||||
| 
 | ||||
|         (span,) = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(span.name, "command") | ||||
|         self.assertEqual(span.status.status_code, StatusCode.ERROR) | ||||
|         self.assertEqual(span.attributes["process.exit.code"], 42) | ||||
|         self.assertEqual(span.attributes["error.type"], "Exit") | ||||
| 
 | ||||
|     @mock.patch("sys.argv", ["command.py"]) | ||||
|     def test_context_object_passing(self): | ||||
|         """Test that instrumentation preserves context object passing.""" | ||||
| 
 | ||||
|         @asyncclick.group() | ||||
|         @asyncclick.option("--debug/--no-debug", default=False) | ||||
|         @asyncclick.pass_context | ||||
|         async def cli(ctx: asyncclick.Context, debug: bool) -> None: | ||||
|             ctx.ensure_object(dict) | ||||
|             ctx.obj["DEBUG"] = debug | ||||
| 
 | ||||
|         @cli.command() | ||||
|         @asyncclick.pass_context | ||||
|         async def command(ctx: asyncclick.Context) -> None: | ||||
|             assert isinstance(ctx.obj, dict) | ||||
|             assert "DEBUG" in ctx.obj | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(cli, ["--debug", "command"]) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
| 
 | ||||
|         (span,) = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(span.name, "command") | ||||
| 
 | ||||
|     def test_multiple_instrumentation(self): | ||||
|         """Test that instrumenting multiple times only applies once.""" | ||||
|         # Already instrumented in setUp, instrument again | ||||
|         AsyncClickInstrumentor().instrument() | ||||
| 
 | ||||
|         @asyncclick.command() | ||||
|         async def command() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         result = run_asyncclick_command_test(command) | ||||
|         self.assertEqual(result.exit_code, 0) | ||||
| 
 | ||||
|         spans = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(len(spans), 1) | ||||
| 
 | ||||
|     def test_concurrency(self): | ||||
|         """Test instrumentation with concurrent command execution.""" | ||||
| 
 | ||||
|         @asyncclick.command() | ||||
|         async def command1() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         @asyncclick.command() | ||||
|         async def command2() -> None: | ||||
|             pass | ||||
| 
 | ||||
|         async def run_both() -> ( | ||||
|             tuple[asyncclick.testing.Result, asyncclick.testing.Result] | ||||
|         ): | ||||
|             runner = CliRunner() | ||||
|             task1 = asyncio.create_task(runner.invoke(command1)) | ||||
|             task2 = asyncio.create_task(runner.invoke(command2)) | ||||
|             results = await asyncio.gather(task1, task2) | ||||
|             return results | ||||
| 
 | ||||
|         results = asyncio.run(run_both()) | ||||
|         self.assertEqual(results[0].exit_code, 0) | ||||
|         self.assertEqual(results[1].exit_code, 0) | ||||
| 
 | ||||
|         spans = self.memory_exporter.get_finished_spans() | ||||
|         self.assertEqual(len(spans), 2) | ||||
|         span_names = [span.name for span in spans] | ||||
|         self.assertIn("command1", span_names) | ||||
|         self.assertIn("command2", span_names) | ||||
|  | @ -36,6 +36,7 @@ dependencies = [ | |||
|     "opentelemetry-instrumentation-aiokafka==0.53b0.dev", | ||||
|     "opentelemetry-instrumentation-aiopg==0.53b0.dev", | ||||
|     "opentelemetry-instrumentation-asgi==0.53b0.dev", | ||||
|     "opentelemetry-instrumentation-asyncclick==0.53b0.dev", | ||||
|     "opentelemetry-instrumentation-asyncio==0.53b0.dev", | ||||
|     "opentelemetry-instrumentation-asyncpg==0.53b0.dev", | ||||
|     "opentelemetry-instrumentation-aws-lambda==0.53b0.dev", | ||||
|  |  | |||
|  | @ -48,6 +48,10 @@ libraries = [ | |||
|         "library": "asgiref ~= 3.0", | ||||
|         "instrumentation": "opentelemetry-instrumentation-asgi==0.53b0.dev", | ||||
|     }, | ||||
|     { | ||||
|         "library": "asyncclick ~= 8.0", | ||||
|         "instrumentation": "opentelemetry-instrumentation-asyncclick==0.53b0.dev", | ||||
|     }, | ||||
|     { | ||||
|         "library": "asyncpg >= 0.12.0", | ||||
|         "instrumentation": "opentelemetry-instrumentation-asyncpg==0.53b0.dev", | ||||
|  |  | |||
|  | @ -196,12 +196,14 @@ pythonVersion = "3.8" | |||
| reportPrivateUsage = false  # Ignore private attributes added by instrumentation packages. | ||||
| # Add progressively instrumentation packages here. | ||||
| include = [ | ||||
|   "instrumentation/opentelemetry-instrumentation-asyncclick", | ||||
|   "instrumentation/opentelemetry-instrumentation-threading", | ||||
|   "instrumentation-genai/opentelemetry-instrumentation-vertexai", | ||||
| ] | ||||
| # 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. | ||||
| exclude = [ | ||||
|   "instrumentation/opentelemetry-instrumentation-asyncclick/tests/**/*.py", | ||||
|   "instrumentation/opentelemetry-instrumentation-threading/tests/**", | ||||
|   "instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/**/*.py", | ||||
|   "instrumentation-genai/opentelemetry-instrumentation-vertexai/examples/**/*.py", | ||||
|  |  | |||
							
								
								
									
										13
									
								
								tox.ini
								
								
								
								
							
							
						
						
									
										13
									
								
								tox.ini
								
								
								
								
							|  | @ -109,6 +109,11 @@ envlist = | |||
|     ; pypy3-test-instrumentation-boto | ||||
|     lint-instrumentation-boto | ||||
| 
 | ||||
|     ; opentelemetry-instrumentation-asyncclick | ||||
|     py3{8,9,10,11,12,13}-test-instrumentation-asyncclick | ||||
|     pypy3-test-instrumentation-asyncclick | ||||
|     lint-instrumentation-asyncclick | ||||
| 
 | ||||
|     ; opentelemetry-instrumentation-click | ||||
|     py3{8,9,10,11,12,13}-test-instrumentation-click | ||||
|     pypy3-test-instrumentation-click | ||||
|  | @ -466,6 +471,9 @@ deps = | |||
|   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 | ||||
| 
 | ||||
|   asyncclick: {[testenv]test_deps} | ||||
|   asyncclick: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncclick/test-requirements.txt | ||||
| 
 | ||||
|   click: {[testenv]test_deps} | ||||
|   click: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-click/test-requirements.txt | ||||
| 
 | ||||
|  | @ -741,6 +749,9 @@ commands = | |||
|   test-instrumentation-asgi: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi/tests {posargs} | ||||
|   lint-instrumentation-asgi: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asgi" | ||||
| 
 | ||||
|   test-instrumentation-asyncclick: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncclick/tests {posargs} | ||||
|   lint-instrumentation-asyncclick: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asyncclick" | ||||
| 
 | ||||
|   test-instrumentation-asyncpg: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncpg/tests {posargs} | ||||
|   lint-instrumentation-asyncpg: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-asyncpg" | ||||
| 
 | ||||
|  | @ -1036,5 +1047,7 @@ deps = | |||
|   {toxinidir}/util/opentelemetry-util-http | ||||
|   {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-vertexai[instruments] | ||||
|   {toxinidir}/instrumentation-genai/opentelemetry-instrumentation-google-genai[instruments] | ||||
|   {toxinidir}/instrumentation/opentelemetry-instrumentation-asyncclick[instruments] | ||||
|    | ||||
| commands = | ||||
|   pyright | ||||
|  |  | |||
							
								
								
									
										63
									
								
								uv.lock
								
								
								
								
							
							
						
						
									
										63
									
								
								uv.lock
								
								
								
								
							|  | @ -20,6 +20,7 @@ members = [ | |||
|     "opentelemetry-instrumentation-aiokafka", | ||||
|     "opentelemetry-instrumentation-aiopg", | ||||
|     "opentelemetry-instrumentation-asgi", | ||||
|     "opentelemetry-instrumentation-asyncclick", | ||||
|     "opentelemetry-instrumentation-asyncio", | ||||
|     "opentelemetry-instrumentation-asyncpg", | ||||
|     "opentelemetry-instrumentation-aws-lambda", | ||||
|  | @ -590,6 +591,42 @@ wheels = [ | |||
|     { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "asyncclick" | ||||
| version = "8.1.7.2" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| resolution-markers = [ | ||||
|     "python_full_version < '3.9'", | ||||
| ] | ||||
| dependencies = [ | ||||
|     { name = "anyio", version = "4.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, | ||||
|     { name = "colorama", marker = "python_full_version < '3.9' and sys_platform == 'win32'" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/5e/bf/59d836c3433d7aa07f76c2b95c4eb763195ea8a5d7f9ad3311ed30c2af61/asyncclick-8.1.7.2.tar.gz", hash = "sha256:219ea0f29ccdc1bb4ff43bcab7ce0769ac6d48a04f997b43ec6bee99a222daa0", size = 349073 } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/1e/6e/9acdbb25733e1de411663b59abe521bec738e72fe4e85843f6ff8b212832/asyncclick-8.1.7.2-py3-none-any.whl", hash = "sha256:1ab940b04b22cb89b5b400725132b069d01b0c3472a9702c7a2c9d5d007ded02", size = 99191 }, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "asyncclick" | ||||
| version = "8.1.8" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| resolution-markers = [ | ||||
|     "python_full_version >= '3.13'", | ||||
|     "python_full_version >= '3.11' and python_full_version < '3.13'", | ||||
|     "python_full_version == '3.10.*'", | ||||
|     "python_full_version == '3.9.*'", | ||||
| ] | ||||
| dependencies = [ | ||||
|     { name = "anyio", version = "4.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, | ||||
|     { name = "colorama", marker = "python_full_version >= '3.9' and sys_platform == 'win32'" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/cb/b5/e1e5fdf1c1bb7e6e614987c120a98d9324bf8edfaa5f5cd16a6235c9d91b/asyncclick-8.1.8.tar.gz", hash = "sha256:0f0eb0f280e04919d67cf71b9fcdfb4db2d9ff7203669c40284485c149578e4c", size = 232900 } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/14/cc/a436f0fc2d04e57a0697e0f87a03b9eaed03ad043d2d5f887f8eebcec95f/asyncclick-8.1.8-py3-none-any.whl", hash = "sha256:eb1ccb44bc767f8f0695d592c7806fdf5bd575605b4ee246ffd5fadbcfdbd7c6", size = 99093 }, | ||||
|     { url = "https://files.pythonhosted.org/packages/92/c4/ae9e9d25522c6dc96ff167903880a0fe94d7bd31ed999198ee5017d977ed/asyncclick-8.1.8.0-py3-none-any.whl", hash = "sha256:be146a2d8075d4fe372ff4e877f23c8b5af269d16705c1948123b9415f6fd678", size = 99115 }, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "asyncpg" | ||||
| version = "0.30.0" | ||||
|  | @ -2861,6 +2898,32 @@ requires-dist = [ | |||
| ] | ||||
| provides-extras = ["instruments"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "opentelemetry-instrumentation-asyncclick" | ||||
| source = { editable = "instrumentation/opentelemetry-instrumentation-asyncclick" } | ||||
| dependencies = [ | ||||
|     { name = "opentelemetry-api" }, | ||||
|     { name = "opentelemetry-semantic-conventions" }, | ||||
|     { name = "typing-extensions" }, | ||||
|     { name = "wrapt" }, | ||||
| ] | ||||
| 
 | ||||
| [package.optional-dependencies] | ||||
| instruments = [ | ||||
|     { name = "asyncclick", version = "8.1.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, | ||||
|     { name = "asyncclick", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, | ||||
| ] | ||||
| 
 | ||||
| [package.metadata] | ||||
| requires-dist = [ | ||||
|     { name = "asyncclick", marker = "extra == 'instruments'", specifier = "~=8.0" }, | ||||
|     { 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 = "typing-extensions", specifier = "~=4.12" }, | ||||
|     { name = "wrapt", specifier = "~=1.0" }, | ||||
| ] | ||||
| provides-extras = ["instruments"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "opentelemetry-instrumentation-asyncio" | ||||
| source = { editable = "instrumentation/opentelemetry-instrumentation-asyncio" } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue