From 596a5f319ea44794d752d599390ee06bf8a6fb95 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Mon, 7 Sep 2026 13:24:37 +0200 Subject: [PATCH 1/5] fix: Require opentelemetry-instrumentation-httpx 0.65b0 for httpx2 instrumentation --- pyproject.toml | 4 +++- uv.lock | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0ac5cf223b..85244ad6eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,9 @@ otel = [ "opentelemetry-api>=1.34.1", "opentelemetry-distro[otlp]>=0.54", "opentelemetry-instrumentation>=0.54", - "opentelemetry-instrumentation-httpx>=0.54", + # 0.65b0 is the first release shipping `HTTPX2ClientInstrumentor`, which instruments the `httpx2` package + # that `HttpxHttpClient` is built on. Older releases only instrument the original `httpx`. + "opentelemetry-instrumentation-httpx>=0.65b0", "opentelemetry-sdk>=1.34.1", "opentelemetry-semantic-conventions>=0.54", "wrapt>=1.17.0", diff --git a/uv.lock b/uv.lock index ee117b2be1..8defbfd642 100644 --- a/uv.lock +++ b/uv.lock @@ -1162,7 +1162,7 @@ requires-dist = [ { name = "opentelemetry-api", marker = "extra == 'otel'", specifier = ">=1.34.1" }, { name = "opentelemetry-distro", extras = ["otlp"], marker = "extra == 'otel'", specifier = ">=0.54" }, { name = "opentelemetry-instrumentation", marker = "extra == 'otel'", specifier = ">=0.54" }, - { name = "opentelemetry-instrumentation-httpx", marker = "extra == 'otel'", specifier = ">=0.54" }, + { name = "opentelemetry-instrumentation-httpx", marker = "extra == 'otel'", specifier = ">=0.65b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.34.1" }, { name = "opentelemetry-semantic-conventions", marker = "extra == 'otel'", specifier = ">=0.54" }, { name = "parsel", marker = "extra == 'parsel'", specifier = ">=1.10.0" }, From 18a51db9daab0e30e16f474a848f2c0624f519ac Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Wed, 16 Sep 2026 10:42:20 +0200 Subject: [PATCH 2/5] chore(deps): Add b0 suffix to the OpenTelemetry pre-release floors --- pyproject.toml | 9 ++++----- uv.lock | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 85244ad6eb..11c97fc9d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,13 +72,12 @@ parsel = ["parsel>=1.10.0"] playwright = ["playwright>=1.27.0", "apify_fingerprint_datapoints>=0.0.2", "browserforge>=1.2.3"] otel = [ "opentelemetry-api>=1.34.1", - "opentelemetry-distro[otlp]>=0.54", - "opentelemetry-instrumentation>=0.54", - # 0.65b0 is the first release shipping `HTTPX2ClientInstrumentor`, which instruments the `httpx2` package - # that `HttpxHttpClient` is built on. Older releases only instrument the original `httpx`. + "opentelemetry-distro[otlp]>=0.54b0", + "opentelemetry-instrumentation>=0.54b0", + # 0.65b0 is the first release shipping `HTTPX2ClientInstrumentor`, the instrumentor for the `httpx2` package. "opentelemetry-instrumentation-httpx>=0.65b0", "opentelemetry-sdk>=1.34.1", - "opentelemetry-semantic-conventions>=0.54", + "opentelemetry-semantic-conventions>=0.54b0", "wrapt>=1.17.0", ] sql_postgres = [ diff --git a/uv.lock b/uv.lock index 8defbfd642..e791973318 100644 --- a/uv.lock +++ b/uv.lock @@ -1160,11 +1160,11 @@ requires-dist = [ { name = "lxml", extras = ["html-clean"], marker = "extra == 'pydantic-ai'", specifier = ">=5.2.0" }, { name = "more-itertools", specifier = ">=10.2.0" }, { name = "opentelemetry-api", marker = "extra == 'otel'", specifier = ">=1.34.1" }, - { name = "opentelemetry-distro", extras = ["otlp"], marker = "extra == 'otel'", specifier = ">=0.54" }, - { name = "opentelemetry-instrumentation", marker = "extra == 'otel'", specifier = ">=0.54" }, + { name = "opentelemetry-distro", extras = ["otlp"], marker = "extra == 'otel'", specifier = ">=0.54b0" }, + { name = "opentelemetry-instrumentation", marker = "extra == 'otel'", specifier = ">=0.54b0" }, { name = "opentelemetry-instrumentation-httpx", marker = "extra == 'otel'", specifier = ">=0.65b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.34.1" }, - { name = "opentelemetry-semantic-conventions", marker = "extra == 'otel'", specifier = ">=0.54" }, + { name = "opentelemetry-semantic-conventions", marker = "extra == 'otel'", specifier = ">=0.54b0" }, { name = "parsel", marker = "extra == 'parsel'", specifier = ">=1.10.0" }, { name = "parsel", marker = "extra == 'pydantic-ai'", specifier = ">=1.10.0" }, { name = "playwright", marker = "extra == 'adaptive-crawler'", specifier = ">=1.27.0" }, From ae6227ba73064e4a2546a5d98956a27f85da38e1 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Wed, 16 Sep 2026 13:54:51 +0200 Subject: [PATCH 3/5] chore(deps): Bump the OpenTelemetry floors to the 0.65b0 release line --- pyproject.toml | 14 ++++++++------ uv.lock | 10 +++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 11c97fc9d0..b9152dc403 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,13 +71,15 @@ httpx = ["httpx2[brotli,http2,zstd]>=2.12.0", "apify_fingerprint_datapoints>=0.0 parsel = ["parsel>=1.10.0"] playwright = ["playwright>=1.27.0", "apify_fingerprint_datapoints>=0.0.2", "browserforge>=1.2.3"] otel = [ - "opentelemetry-api>=1.34.1", - "opentelemetry-distro[otlp]>=0.54b0", - "opentelemetry-instrumentation>=0.54b0", - # 0.65b0 is the first release shipping `HTTPX2ClientInstrumentor`, the instrumentor for the `httpx2` package. + # The OpenTelemetry packages release in lockstep and pin each other with `==`, so one floor covers the + # whole group. 0.65b0 (paired with 1.44.0 on the stable line) is the first release with + # `HTTPX2ClientInstrumentor`, the instrumentor for the `httpx2` package that `HttpxHttpClient` runs on. + "opentelemetry-api>=1.44.0", + "opentelemetry-distro[otlp]>=0.65b0", + "opentelemetry-instrumentation>=0.65b0", "opentelemetry-instrumentation-httpx>=0.65b0", - "opentelemetry-sdk>=1.34.1", - "opentelemetry-semantic-conventions>=0.54b0", + "opentelemetry-sdk>=1.44.0", + "opentelemetry-semantic-conventions>=0.65b0", "wrapt>=1.17.0", ] sql_postgres = [ diff --git a/uv.lock b/uv.lock index e791973318..2e7cfd2e9f 100644 --- a/uv.lock +++ b/uv.lock @@ -1159,12 +1159,12 @@ requires-dist = [ { name = "jaro-winkler", marker = "extra == 'adaptive-crawler'", specifier = ">=2.0.3" }, { name = "lxml", extras = ["html-clean"], marker = "extra == 'pydantic-ai'", specifier = ">=5.2.0" }, { name = "more-itertools", specifier = ">=10.2.0" }, - { name = "opentelemetry-api", marker = "extra == 'otel'", specifier = ">=1.34.1" }, - { name = "opentelemetry-distro", extras = ["otlp"], marker = "extra == 'otel'", specifier = ">=0.54b0" }, - { name = "opentelemetry-instrumentation", marker = "extra == 'otel'", specifier = ">=0.54b0" }, + { name = "opentelemetry-api", marker = "extra == 'otel'", specifier = ">=1.44.0" }, + { name = "opentelemetry-distro", extras = ["otlp"], marker = "extra == 'otel'", specifier = ">=0.65b0" }, + { name = "opentelemetry-instrumentation", marker = "extra == 'otel'", specifier = ">=0.65b0" }, { name = "opentelemetry-instrumentation-httpx", marker = "extra == 'otel'", specifier = ">=0.65b0" }, - { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.34.1" }, - { name = "opentelemetry-semantic-conventions", marker = "extra == 'otel'", specifier = ">=0.54b0" }, + { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.44.0" }, + { name = "opentelemetry-semantic-conventions", marker = "extra == 'otel'", specifier = ">=0.65b0" }, { name = "parsel", marker = "extra == 'parsel'", specifier = ">=1.10.0" }, { name = "parsel", marker = "extra == 'pydantic-ai'", specifier = ">=1.10.0" }, { name = "playwright", marker = "extra == 'adaptive-crawler'", specifier = ">=1.27.0" }, From dd5083588cef17a6a690f74a2327005aa8d820b4 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Wed, 16 Sep 2026 14:07:01 +0200 Subject: [PATCH 4/5] chore(deps): Drop the comment from the otel extra --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b9152dc403..640f87d262 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,9 +71,6 @@ httpx = ["httpx2[brotli,http2,zstd]>=2.12.0", "apify_fingerprint_datapoints>=0.0 parsel = ["parsel>=1.10.0"] playwright = ["playwright>=1.27.0", "apify_fingerprint_datapoints>=0.0.2", "browserforge>=1.2.3"] otel = [ - # The OpenTelemetry packages release in lockstep and pin each other with `==`, so one floor covers the - # whole group. 0.65b0 (paired with 1.44.0 on the stable line) is the first release with - # `HTTPX2ClientInstrumentor`, the instrumentor for the `httpx2` package that `HttpxHttpClient` runs on. "opentelemetry-api>=1.44.0", "opentelemetry-distro[otlp]>=0.65b0", "opentelemetry-instrumentation>=0.65b0", From 3346b12817681e3a4d0af68884f7103c10b6f4f0 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Thu, 24 Sep 2026 13:06:05 +0200 Subject: [PATCH 5/5] chore(deps): Drop opentelemetry-instrumentation-httpx from the otel extra --- docs/guides/trace_and_monitor_crawlers.mdx | 8 +++ pyproject.toml | 11 ++-- uv.lock | 58 ++++++---------------- 3 files changed, 28 insertions(+), 49 deletions(-) diff --git a/docs/guides/trace_and_monitor_crawlers.mdx b/docs/guides/trace_and_monitor_crawlers.mdx index df740dcf73..cfa27730f7 100644 --- a/docs/guides/trace_and_monitor_crawlers.mdx +++ b/docs/guides/trace_and_monitor_crawlers.mdx @@ -35,6 +35,14 @@ In the following example, you can see the function `instrument_crawler` that con {InstrumentCrawler} +The `otel` extra doesn't instrument HTTP clients. To also trace requests sent by `HttpxHttpClient`, install the httpx instrumentation: + +```bash +python -m pip install 'opentelemetry-instrumentation-httpx>=0.65b0' +``` + +Then call `HTTPX2ClientInstrumentor().instrument()` from `opentelemetry.instrumentation.httpx` next to the crawler instrumentation. `HttpxHttpClient` runs on the `httpx2` package, so `HTTPXClientInstrumentor` from the same module records no spans for it. + ## Analyze the results In the Jaeger UI, you can search for different traces, apply filtering, compare traces, view their detailed attributes, view timing details, and more. For the detailed description of the tool's capabilities, please refer to the [Jaeger documentation](https://www.jaegertracing.io/docs/1.47/deployment/frontend-ui/#trace-page). diff --git a/pyproject.toml b/pyproject.toml index 640f87d262..debd7a5452 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,12 +71,11 @@ httpx = ["httpx2[brotli,http2,zstd]>=2.12.0", "apify_fingerprint_datapoints>=0.0 parsel = ["parsel>=1.10.0"] playwright = ["playwright>=1.27.0", "apify_fingerprint_datapoints>=0.0.2", "browserforge>=1.2.3"] otel = [ - "opentelemetry-api>=1.44.0", - "opentelemetry-distro[otlp]>=0.65b0", - "opentelemetry-instrumentation>=0.65b0", - "opentelemetry-instrumentation-httpx>=0.65b0", - "opentelemetry-sdk>=1.44.0", - "opentelemetry-semantic-conventions>=0.65b0", + "opentelemetry-api>=1.34.1", + "opentelemetry-distro[otlp]>=0.54", + "opentelemetry-instrumentation>=0.54", + "opentelemetry-sdk>=1.34.1", + "opentelemetry-semantic-conventions>=0.54", "wrapt>=1.17.0", ] sql_postgres = [ diff --git a/uv.lock b/uv.lock index 2e7cfd2e9f..6ec22488de 100644 --- a/uv.lock +++ b/uv.lock @@ -3,10 +3,10 @@ revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version >= '3.14' and sys_platform != 'emscripten'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", "python_full_version == '3.13.*' and sys_platform != 'emscripten'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version == '3.12.*' and sys_platform != 'emscripten'", "python_full_version == '3.11.*'", "python_full_version < '3.11'", @@ -1024,7 +1024,6 @@ all = [ { name = "opentelemetry-api" }, { name = "opentelemetry-distro", extra = ["otlp"] }, { name = "opentelemetry-instrumentation" }, - { name = "opentelemetry-instrumentation-httpx" }, { name = "opentelemetry-sdk" }, { name = "opentelemetry-semantic-conventions" }, { name = "parsel" }, @@ -1061,7 +1060,6 @@ otel = [ { name = "opentelemetry-api" }, { name = "opentelemetry-distro", extra = ["otlp"] }, { name = "opentelemetry-instrumentation" }, - { name = "opentelemetry-instrumentation-httpx" }, { name = "opentelemetry-sdk" }, { name = "opentelemetry-semantic-conventions" }, { name = "wrapt" }, @@ -1159,12 +1157,11 @@ requires-dist = [ { name = "jaro-winkler", marker = "extra == 'adaptive-crawler'", specifier = ">=2.0.3" }, { name = "lxml", extras = ["html-clean"], marker = "extra == 'pydantic-ai'", specifier = ">=5.2.0" }, { name = "more-itertools", specifier = ">=10.2.0" }, - { name = "opentelemetry-api", marker = "extra == 'otel'", specifier = ">=1.44.0" }, - { name = "opentelemetry-distro", extras = ["otlp"], marker = "extra == 'otel'", specifier = ">=0.65b0" }, - { name = "opentelemetry-instrumentation", marker = "extra == 'otel'", specifier = ">=0.65b0" }, - { name = "opentelemetry-instrumentation-httpx", marker = "extra == 'otel'", specifier = ">=0.65b0" }, - { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.44.0" }, - { name = "opentelemetry-semantic-conventions", marker = "extra == 'otel'", specifier = ">=0.65b0" }, + { name = "opentelemetry-api", marker = "extra == 'otel'", specifier = ">=1.34.1" }, + { name = "opentelemetry-distro", extras = ["otlp"], marker = "extra == 'otel'", specifier = ">=0.54" }, + { name = "opentelemetry-instrumentation", marker = "extra == 'otel'", specifier = ">=0.54" }, + { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.34.1" }, + { name = "opentelemetry-semantic-conventions", marker = "extra == 'otel'", specifier = ">=0.54" }, { name = "parsel", marker = "extra == 'parsel'", specifier = ">=1.10.0" }, { name = "parsel", marker = "extra == 'pydantic-ai'", specifier = ">=1.10.0" }, { name = "playwright", marker = "extra == 'adaptive-crawler'", specifier = ">=1.27.0" }, @@ -2984,10 +2981,10 @@ version = "2.5.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version >= '3.14' and sys_platform != 'emscripten'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", "python_full_version == '3.13.*' and sys_platform != 'emscripten'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version == '3.12.*' and sys_platform != 'emscripten'", ] sdist = { url = "https://files.pythonhosted.org/packages/13/01/11703282db468b85f6f7b8c7f22d058de5970d5c7e60a3a8aaa313c3de36/numpy-2.5.3.tar.gz", hash = "sha256:df2d5874ff183595a4ba404edd04f6bd9b5505c1d7708573f6a6c17489a67563", size = 20791231, upload-time = "2026-09-06T16:27:47.073Z" } @@ -3183,22 +3180,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/40/7b/85eab1215f72adf0e68d3dc4a679b9bff993fa679ff34cd8dd378e2659fd/opentelemetry_instrumentation-0.65b0-py3-none-any.whl", hash = "sha256:ea967a72b9939b5fcfdad572753b4306c59dcb99e3f382d95dae04286805e137", size = 36717, upload-time = "2026-07-16T15:24:51.424Z" }, ] -[[package]] -name = "opentelemetry-instrumentation-httpx" -version = "0.65b0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-instrumentation" }, - { name = "opentelemetry-semantic-conventions" }, - { name = "opentelemetry-util-http" }, - { name = "wrapt" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/03/a529140241addd4d0acc73bafbd6f74691651b92fc0ae9b4513cf80f07fa/opentelemetry_instrumentation_httpx-0.65b0.tar.gz", hash = "sha256:4627aa9c6bb99bf4462c8b565b0ef6aeb9ffad95c6c92868be1ef7895de112ee", size = 26309, upload-time = "2026-07-16T15:26:07.973Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/0f/c6144096b4914bbf44b43ba21c962e8f333ff045770b50a3e79ed8bd455f/opentelemetry_instrumentation_httpx-0.65b0-py3-none-any.whl", hash = "sha256:400f1b78afa4ee2332b5debe58e1ed1b317913d58812c952576be76660aeadb1", size = 17436, upload-time = "2026-07-16T15:25:15.772Z" }, -] - [[package]] name = "opentelemetry-proto" version = "1.44.0" @@ -3238,15 +3219,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a6/0e/49df70d9b81fb5cbae4bbf2a49d865b09bcbcbc4eb53f5851b1027738d78/opentelemetry_semantic_conventions-0.65b0-py3-none-any.whl", hash = "sha256:1cacde7b0ad306f84c5ef08c3dbe1bbaf20165bba6f8bff43b670e555a086bcb", size = 204645, upload-time = "2026-07-16T15:25:30.688Z" }, ] -[[package]] -name = "opentelemetry-util-http" -version = "0.65b0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/32/a9/d7525a59fdd240e69b5af4a6338e78fafa1b4203394122cbd6701fb5f84a/opentelemetry_util_http-0.65b0.tar.gz", hash = "sha256:84f82d826978bba416ab453460ff6a7391cdc3534c93a786595e4068680016b7", size = 11243, upload-time = "2026-07-16T15:26:27.898Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/23/3f/ab8d29df207ce5f470a07fa96ebb48af4e95b7fab7e7635311b9a32f2fab/opentelemetry_util_http-0.65b0-py3-none-any.whl", hash = "sha256:7553b606f963097cb190536dc30556cce85090692e471a422fff30ca29b04348", size = 8245, upload-time = "2026-07-16T15:25:46.482Z" }, -] - [[package]] name = "packaging" version = "26.3" @@ -4339,10 +4311,10 @@ version = "1.9.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version >= '3.14' and sys_platform != 'emscripten'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", "python_full_version == '3.13.*' and sys_platform != 'emscripten'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version == '3.12.*' and sys_platform != 'emscripten'", "python_full_version == '3.11.*'", ] @@ -4540,10 +4512,10 @@ version = "1.18.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version >= '3.14' and sys_platform != 'emscripten'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", "python_full_version == '3.13.*' and sys_platform != 'emscripten'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version == '3.12.*' and sys_platform != 'emscripten'", ] dependencies = [ @@ -5460,10 +5432,10 @@ version = "17.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version >= '3.14' and sys_platform != 'emscripten'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", "python_full_version == '3.13.*' and sys_platform != 'emscripten'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version == '3.12.*' and sys_platform != 'emscripten'", "python_full_version == '3.11.*'", ]