Skip to content

Feature branch for httpx2 migration: agnostic protos, exception types, and integration rewrites only#22676

Draft
mwdd146980 wants to merge 66 commits into
masterfrom
mwdd146980/httpx-migration-base
Draft

Feature branch for httpx2 migration: agnostic protos, exception types, and integration rewrites only#22676
mwdd146980 wants to merge 66 commits into
masterfrom
mwdd146980/httpx-migration-base

Conversation

@mwdd146980

@mwdd146980 mwdd146980 commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Feature branch for the requests to httpx migration. Introduces library-agnostic HTTP infrastructure and decouples integration tests from requests internals. See the RFC for full context.

@codecov

codecov Bot commented Feb 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.17915% with 74 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.11%. Comparing base (656fac7) to head (dc5a6d5).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread datadog_checks_base/changelog.d/22676.added Outdated
Comment thread datadog_checks_base/datadog_checks/base/utils/http_protocol.py
Comment thread datadog_checks_base/datadog_checks/base/utils/http_exceptions.py Outdated
@mwdd146980
mwdd146980 force-pushed the mwdd146980/httpx-migration-base branch from beb72ad to 07a9003 Compare February 20, 2026 19:16

mwdd146980 commented Feb 20, 2026

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

mwdd146980 and others added 2 commits May 28, 2026 11:57
…roxy tests to mock_openmetrics_http (#23781)

* kube small batch: migrate test fixtures to mock_openmetrics_http

Migrate kube_apiserver_metrics, kube_dns, kube_metrics_server, and
kube_proxy off requests.Session.get patches to mock_openmetrics_http
+ MockHTTPResponse. Test-only changes, no production code touched.

Adds shared make_mock_metrics helpers in each integration's
tests/common.py and opt-in mock_healthcheck_wrapper fixtures in
kube_dns, kube_metrics_server, kube_proxy conftests to neutralize
_healthcheck_http_handler's separate RequestsWrapper instances.

Replaces test_service_check_ok in three integrations with a
parametrized test_service_check that exercises both the OK branch
and the requests.HTTPError branch against the production
except requests.exceptions.RequestException handler.

* kube small batch: address review pass 1 (kwargs dict in test_service_check)

* kube small batch: address review pass 2 (inline kwargs into parametrize)

* kube small batch: fix license header years on new files
mwdd146980 and others added 4 commits June 24, 2026 12:23
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Defer nutanix requests->httpx2 test decoupling to a complete post-wrapper rework.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Add HTTPXWrapper backed by httpx2 behind use_httpx flag

* Address Round 1 review findings

* Tighten comments from human review

* Use httpx2 directly instead of aliasing as httpx

* Rename to httpx2

* Rename HTTPXWrapper symbols to HTTPX2Wrapper

* Round 2 finding #3: move test_stream_connection_lines to OM scraper test dir

* Round 2 finding #7: drop unreachable __del__ AttributeError

* Round 2 finding #4: drop dead DEFAULT_REMAPPED_FIELDS constant

* Round 2 finding #9: simplify lifecycle import-failure test

* Round 2 finding #8: assert stream-kwarg drop log via caplog

* Round 2 finding #5: extract _build_http_client helper

* Round 2 finding #10: case-fold headers/extra_headers merge

* Round 2 finding #6: close response on adapter wrap failure

* Round 2 finding #1: map httpx2 exceptions in iter_lines/iter_content

* Round 3 fix #4: tighten ImportError assertion to exc.value.name

* Round 3 fix #2: iter_lines bytes-through fidelity

* Round 3 fix #3: derive passthrough from REQUEST_KWARGS

* Round 3 fix #1: timeout=None guard + scalar _make_timeout consistency

* Round 4 fix #1: map mid-stream httpx2 errors to HTTPConnectionError

* Round 4 fix #4: document init header dict-shape parity with RequestsWrapper

* Round 4 fix #3: add encoding/url/cookies/elapsed to HTTPResponseProtocol

* Round 4 fix #2: replace bytes accumulator with bytearray in iter_lines

* Round 5 finding #5: tighten HTTPResponseProtocol.cookies to Mapping[str, str]

* Round 5 finding #1: collapse _map_httpx2_exception branches via httpx2.NetworkError

* Round 5 finding #2: lock in iter_lines decode CRLF parity test

* Round 5 finding #4: lock in headers={} benign no-op behavior

* Round 5 finding #3: document options['headers'] mirror constraint

* Round 5 finding #6: use getattr guard in test_lifecycle teardown

* Round 5 finding #7: rename misleading iter_lines bytes-path test

* Round 5 finding #8: drop tautological protocol attrs test

* Round 6 finding #1: collapse follow_redirects routing

* Round 6 finding #2: assert request kwargs invariant at import

* Round 7 finding #1: http-response-protocol-encoding-setter

* Round 7 finding #2: follow-redirects-positive-test-coverage

* Round 8 finding #1: wrap-content-text-json-exceptions

* Round 8 finding #4: parametrize-warning-path-tests

* Map self.options['headers'] mutations to httpx2 requests

* Improve HTTPX2Wrapper TypeError with per-kwarg remediation hints

* Tighten test_stream_kwarg_still_silently_dropped to assert response, not call count

* Add allow_redirects hint to UNKNOWN_KWARG_HINTS

* Drop dead _client.headers writes from set_header

* Accept per-request auth kwarg in HTTPX2Wrapper

* Type-hint _build_http_client instance parameter

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Document SSL folds into HTTPConnectionError in _map_httpx2_exception

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gration-base

# Conflicts:
#	datadog_checks_base/datadog_checks/base/checks/base.py
#	fluxcd/tests/conftest.py
mwdd146980 and others added 3 commits June 29, 2026 10:52
…ptions hierarchy (#24212)

* Swap mesos_master and control_m test exceptions to agnostic http_exceptions

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add mesos_master changelog entry for httpx HTTPTimeoutError handling

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ap the test (#24213)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mwdd146980 and others added 10 commits July 2, 2026 09:45
… test (#24280)

* Catch agnostic HTTP error types across cloud_foundry_api and swap the test

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* rename changelog entry from .changed to .fixed

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…gration-base

# Conflicts:
#	cloud_foundry_api/tests/test_cloud_foundry_api.py
#	elastic/tests/test_unit.py
#	temporal/tests/conftest.py
…4310)

* Translate requests exceptions to agnostic types at the RequestsWrapper boundary

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add increment-2 seam coverage tests for the exception translator

Cover the translator directly (full mapping table with an exact-type ordering
guard), the streaming seam (iter_content/iter_lines), the buffered seam
(content/text/json via a failing-response stand-in), and JSON parse convergence
to the stdlib json.JSONDecodeError.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Catch agnostic HTTPConnectionError in OpenMetrics v2 scraper

The wrapper now raises HTTPConnectionError, which the requests-only catch in
stream_connection_lines no longer matched, silently disabling
ignore_connection_errors for OM v2. Narrow the catch to the agnostic type and
drop the dead requests import.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review findings: dedup translator, extract context manager, fix poll docstrings

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Carry the agnostic wrapper on HTTPStatusError.response instead of the raw response

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Translate auth-token fetch exceptions at the RequestsWrapper boundary

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Translate direct iteration of a streamed response at the wrapper boundary

ResponseWrapper overrode iter_content/iter_lines but not __iter__, so a
direct `for chunk in response` forwarded through wrapt to the raw
requests.Response, whose __iter__ delegates to the raw iter_content and
re-raised untranslated requests exceptions. Override __iter__ to route
through the translating iter_content, keeping the wrapper the sole
translation choke point.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(base): catch connect timeouts in OM v2 scraper

Round-2 review of PR #24310 found the OpenMetrics v2 stream scraper
narrowed its `except ConnectionError` to `except HTTPConnectionError`.
The translator maps requests' ConnectTimeout to HTTPTimeoutError (a
sibling, not a subclass), so connect timeouts under
ignore_connection_errors=True escaped instead of being swallowed. Catch
both agnostic types and parametrize the test over them.

Also address the round's minor findings:
- route ResponseWrapper.raise_for_status through _translate_requests_exception
  via a new optional response= param, dropping duplicated extraction
- add type hints to the two new module-level translation helpers
- drop the unlinked Step 0.1 subpage reference from the translator docstring
- finish the half-migrated poll() docstrings (requests.Response -> response)
- add the 24310.changed changelog entry

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(base): type response param and add __iter__ to protocol

Round-3 review polish for PR #24310:
- annotate the response kwarg on _translate_requests_exception (ResponseWrapper | None)
- declare __iter__ on HTTPResponseProtocol so the frozen contract matches the
  ResponseWrapper.__iter__ seam this PR added

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(base): add __iter__ to MockHTTPResponse for protocol parity

HTTPResponseProtocol gained __iter__ in this PR; give the mock the same
iter_content(128) delegation so a test iterating a mock_http response
doesn't raise TypeError.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(base): note ReadTimeout is swallowed under ignore_connection_errors

The (HTTPConnectionError, HTTPTimeoutError) catch in stream_connection_lines
also swallows a mid-stream ReadTimeout under ignore_connection_errors, since
the agnostic hierarchy has no connect-vs-read timeout distinction. Document
this as intentional per round-5 review feedback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(base): re-home changelog entry under PR 22676

24310 merges into the httpx-migration-base feature branch (PR 22676), which
merges to master. Rename 24310.changed to 22676.changed so the behavior-change
entry appears under the PR that actually reaches master. It coexists with the
existing 22676.added (additive infra); together they reflect the full batch, and
the .changed entry preserves the major version bump.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(base): consolidate the floor batch into one changelog entry

Fold 22676.added into 22676.changed so the batch merging to master carries a
single entry. The behavior change (agnostic exceptions) makes the whole batch a
major bump, so the consolidated entry is typed changed and also covers the
added agnostic mocks/proto/exceptions and test migration.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: catch backend-agnostic HTTP exceptions

The base RequestsWrapper now raises the backend-agnostic exceptions in
datadog_checks.base.utils.http_exceptions instead of requests.exceptions,
so these checks must catch the agnostic types to keep working after the
httpx migration. Narrow the production catch sites and update the coupled
test assertions accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(openstack): route calls through the shared HTTP client

Route the seven bare requests calls (three instance methods and the four
auth/catalog classmethods, via a threaded http client) through self.http,
so they raise backend-agnostic exceptions after the httpx migration. Narrow
the ~10 catch sites to the agnostic types and drop import requests. ssl_verify
is an init_config option here, so bridge it to the instance-level tls_verify
the shared client resolves.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(openstack): extract shared transport-error tuple

The agnostic reachability-failure tuple (HTTPStatusError,
HTTPTimeoutError, HTTPConnectionError) was repeated at six catch
sites. Extract it into the API_TRANSPORT_ERRORS module constant so
the next migration batch has a single place to update.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(openstack): require http on the live auth worker methods

request_auth_token, get_token_for_project, and request_project_list
dereference http immediately and are always called with a real client.
Drop the http=None default so a missing argument fails fast with a
TypeError at the call site instead of an opaque AttributeError deep in
the method. The from_config entry points keep the default because they
can raise IncompleteConfig before http is used.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* revert(openstack): keep the legacy integration untouched

The standalone openstack integration is legacy and close to
deprecation. Per team decision, leave it exactly as it is rather than
migrate it onto the shared HTTP client. This backs out all of this
PR's openstack changes (self.http routing, the ssl_verify to
tls_verify bridge, the required-http signatures, and the agnostic
catch-site narrowing), restoring the file to the feature-branch base.
openstack keeps its bare requests calls and catches requests
exceptions, so it is unaffected by the wrapper exception translation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(openstack): agnosticize exceptions, preserving behavior

Route the OpenStack API and Keystone auth requests through the shared
HTTP client and catch the backend-agnostic HTTPStatusError,
HTTPTimeoutError, and HTTPConnectionError instead of requests
exceptions. Behavior is preserved: the Keystone auth request keeps its
legacy default of skipping TLS verification unless ssl_verify is set,
carried through as an explicit per-call verify override rather than
inheriting the shared client's verify-by-default. The dormant
unscoped-catalog fallback is left in place untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(changelog): reword entries to be customer-facing

Rewrite the httpx floor changelog entries in plain language centered on
the actual change (backend-agnostic HTTP exceptions), dropping the
internal migration references and the exception class-name lists. The
base entry keeps its .changed classification since raising different
exception types is breaking for anything catching requests errors off
self.http.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gration-base

# Conflicts:
#	scylla/tests/conftest.py
@dd-octo-sts

dd-octo-sts Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Validation Report

All 21 validations passed.

Show details
Validation Description Status
agent-reqs Verify check versions match the Agent requirements file
ci Validate CI configuration and code coverage settings
codeowners Validate every integration has a CODEOWNERS entry
config Validate default configuration files against spec.yaml
dep Verify dependency pins are consistent and Agent-compatible
http Validate integrations use the HTTP wrapper correctly
imports Validate check imports do not use deprecated modules
integration-style Validate check code style conventions
jmx-metrics Validate JMX metrics definition files and config
labeler Validate PR labeler config matches integration directories
legacy-signature Validate no integration uses the legacy Agent check signature
license-headers Validate Python files have proper license headers
licenses Validate third-party license attribution list
metadata Validate metadata.csv metric definitions
models Validate configuration data models match spec.yaml
openmetrics Validate OpenMetrics integrations disable the metric limit
package Validate Python package metadata and naming
qa-label Validate the pull request declares whether it needs QA for the next Agent release
readmes Validate README files have required sections
saved-views Validate saved view JSON file structure and fields
version Validate version consistency between package and changelog

View full run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent/review-requested base_package dev_package ecosystems/review-requested integration/airflow integration/amazon_msk integration/apache integration/appgate_sdp integration/arangodb integration/argo_workflows integration/avi_vantage integration/azure_iot_edge integration/celery integration/cert_manager integration/cilium integration/citrix_hypervisor integration/cloud_foundry_api integration/consul integration/control_m integration/couch integration/couchbase integration/datadog_cluster_agent integration/dcgm  integration/druid integration/ecs_fargate integration/elastic integration/envoy integration/etcd integration/external_dns integration/falco integration/fluxcd integration/fly_io integration/gitlab_runner integration/gitlab integration/haproxy integration/harbor integration/hdfs_datanode integration/hdfs_namenode integration/http_check integration/ibm_was integration/impala integration/istio integration/kube_apiserver_metrics integration/kube_controller_manager integration/kube_dns integration/kube_metrics_server integration/kube_proxy integration/kube_scheduler integration/kubelet integration/kubevirt_api integration/kubevirt_controller integration/kubevirt_handler integration/linkerd integration/mapreduce integration/marathon integration/mesos_master integration/mesos_slave integration/n8n integration/nginx integration/nutanix integration/nvidia_nim integration/nvidia_triton integration/octopus_deploy integration/openmetrics integration/openstack_controller integration/openstack integration/php_fpm integration/powerdns_recursor integration/prometheus integration/proxmox integration/quarkus integration/rabbitmq integration/ray integration/riak integration/scylla integration/sonarqube integration/sonatype_nexus integration/spark integration/squid integration/strimzi integration/teamcity integration/tekton integration/temporal integration/torchserve integration/traefik_mesh integration/twistlock integration/vault integration/vllm integration/voltdb integration/vsphere integration/yarn product/review-requested qa/required QA is required for this PR and will generate a QA card

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants