From f2206fdc08f1d06c8501e66c1f74fc86246b59fe Mon Sep 17 00:00:00 2001 From: HardMax71 Date: Sat, 3 Oct 2026 15:14:06 +0200 Subject: [PATCH] fix(http): honor and deprecate HttpxRequestAdapter's base_url argument Since 1.9.4 the adapter ignored its base_url argument without a word. Requests then failed with an unrelated URL error, or under a generated client went to the client's default server. An explicit base_url wins over the http client's again, as it did up to 1.9.3. Passing it now raises a DeprecationWarning that points to the http client or the base_url setter, since the other kiota adapters take the base URL from the client only. Fixes #501. --- .../httpx/kiota_http/httpx_request_adapter.py | 12 +++++++++++- .../httpx/tests/test_httpx_request_adapter.py | 18 ++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/http/httpx/kiota_http/httpx_request_adapter.py b/packages/http/httpx/kiota_http/httpx_request_adapter.py index c63f3907..ffffa04f 100644 --- a/packages/http/httpx/kiota_http/httpx_request_adapter.py +++ b/packages/http/httpx/kiota_http/httpx_request_adapter.py @@ -2,6 +2,7 @@ from __future__ import annotations import re +import warnings from datetime import datetime from typing import Any, Optional, TypeVar, Union from urllib import parse @@ -87,7 +88,16 @@ def __init__( if not http_client: http_client = KiotaClientFactory.create_with_default_middleware() self._http_client: httpx.AsyncClient = http_client - self._base_url: str = str(http_client.base_url) if http_client.base_url is not None else "" + if base_url: + warnings.warn( + "The base_url argument is deprecated. " + "Set base_url on the http_client or on the request adapter instead.", + DeprecationWarning, + stacklevel=2 + ) + else: + base_url = str(http_client.base_url) if http_client.base_url is not None else "" + self._base_url: str = base_url if not observability_options: observability_options = ObservabilityOptions() self.observability_options = observability_options diff --git a/packages/http/httpx/tests/test_httpx_request_adapter.py b/packages/http/httpx/tests/test_httpx_request_adapter.py index 173cb6aa..3b67b3aa 100644 --- a/packages/http/httpx/tests/test_httpx_request_adapter.py +++ b/packages/http/httpx/tests/test_httpx_request_adapter.py @@ -1,5 +1,6 @@ import asyncio import logging +import warnings from unittest.mock import AsyncMock, Mock, call, patch from urllib.parse import unquote @@ -626,11 +627,20 @@ async def test_send_primitive_async_302_with_location_header_does_not_throw( assert "location" in resp.headers await request_adapter.send_primitive_async(request_info, "float", {}) -def test_httpx_request_adapter_ignores_base_url_parameter(auth_provider): - request_adapter = HttpxRequestAdapter(auth_provider, base_url="https://no.com") - assert request_adapter.base_url == "" +def test_httpx_request_adapter_uses_base_url_parameter(auth_provider): + with pytest.warns(DeprecationWarning, match="base_url argument is deprecated"): + request_adapter = HttpxRequestAdapter(auth_provider, base_url="https://no.com") + assert request_adapter.base_url == "https://no.com" + +def test_httpx_request_adapter_base_url_parameter_wins_over_http_client(auth_provider): + http_client = httpx.AsyncClient(base_url=BASE_URL) + with pytest.warns(DeprecationWarning, match="base_url argument is deprecated"): + request_adapter = HttpxRequestAdapter(auth_provider, http_client=http_client, base_url="https://no.com") + assert request_adapter.base_url == "https://no.com" def test_httpx_request_adapter_uses_http_client_base_url(auth_provider): http_client = httpx.AsyncClient(base_url=BASE_URL) - request_adapter = HttpxRequestAdapter(auth_provider, http_client=http_client, base_url="https://no.com") + with warnings.catch_warnings(): + warnings.simplefilter("error") + request_adapter = HttpxRequestAdapter(auth_provider, http_client=http_client) assert request_adapter.base_url == BASE_URL