This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new bd46aa1058e fix(http): Fix HttpHook.url_from_endpoint() lazy
initialization (#54202)
bd46aa1058e is described below
commit bd46aa1058e19bb22c238954539f6fe4c0953bce
Author: Gary Hsu <[email protected]>
AuthorDate: Tue Aug 19 08:15:34 2025 +0800
fix(http): Fix HttpHook.url_from_endpoint() lazy initialization (#54202)
* fix(http): fix HttpHook.url_from_endpoint() without get_conn() call
- Add _base_url_initialized flag to track initialization state
- Implement lazy initialization in url_from_endpoint() method
- Fix issue where url_from_endpoint() returns incorrect URL when called
independently
* Add modification on url_from_endpoint to make sure base_url is set
---
.../http/src/airflow/providers/http/hooks/http.py | 6 ++++++
providers/http/tests/unit/http/hooks/test_http.py | 23 ++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/providers/http/src/airflow/providers/http/hooks/http.py
b/providers/http/src/airflow/providers/http/hooks/http.py
index b789688a5d8..b8baa580c41 100644
--- a/providers/http/src/airflow/providers/http/hooks/http.py
+++ b/providers/http/src/airflow/providers/http/hooks/http.py
@@ -135,6 +135,7 @@ class HttpHook(BaseHook):
self.http_conn_id = http_conn_id
self.method = method.upper()
self.base_url: str = ""
+ self._base_url_initialized: bool = False
self._retry_obj: Callable[..., Any]
self._auth_type: Any = auth_type
@@ -203,6 +204,7 @@ class HttpHook(BaseHook):
parsed = urlparse(self.base_url)
if not parsed.scheme:
raise ValueError(f"Invalid base URL: Missing scheme in
{self.base_url}")
+ self._base_url_initialized = True
def _configure_session_from_auth(self, session: Session, connection:
Connection) -> Session:
session.auth = self._extract_auth(connection)
@@ -383,6 +385,10 @@ class HttpHook(BaseHook):
def url_from_endpoint(self, endpoint: str | None) -> str:
"""Combine base url with endpoint."""
+ # Ensure base_url is set by initializing it if it hasn't been
initialized yet
+ if not self._base_url_initialized and not self.base_url:
+ connection = self.get_connection(self.http_conn_id)
+ self._set_base_url(connection)
return _url_from_endpoint(base_url=self.base_url, endpoint=endpoint)
def test_connection(self):
diff --git a/providers/http/tests/unit/http/hooks/test_http.py
b/providers/http/tests/unit/http/hooks/test_http.py
index 9f60fee30ed..7ebc9754cc8 100644
--- a/providers/http/tests/unit/http/hooks/test_http.py
+++ b/providers/http/tests/unit/http/hooks/test_http.py
@@ -612,8 +612,31 @@ class TestHttpHook:
def test_url_from_endpoint(self, base_url: str, endpoint: str,
expected_url: str):
hook = HttpHook()
hook.base_url = base_url
+ hook._base_url_initialized = True # Mark as initialized to prevent
lazy loading
assert hook.url_from_endpoint(endpoint) == expected_url
+ @mock.patch("airflow.providers.http.hooks.http.HttpHook.get_connection")
+ def test_url_from_endpoint_lazy_initialization(self, mock_get_connection):
+ """Test that url_from_endpoint works without calling get_conn()
first."""
+ # Mock the connection
+ mock_connection = mock.MagicMock()
+ mock_connection.host = "foo.bar.com"
+ mock_connection.schema = "https"
+ mock_connection.port = None
+ mock_get_connection.return_value = mock_connection
+
+ # Create hook without calling get_conn() and verify that base_url is
not initialized
+ hook = HttpHook(http_conn_id="test_conn")
+ assert not hook._base_url_initialized
+
+ # This should work now with our fix and verify the URL was constructed
correctly
+ url = hook.url_from_endpoint("baz/bop")
+ assert url == "https://foo.bar.com/baz/bop"
+
+ # Verify get_connection was called and and verify that base_url is now
initialized
+ mock_get_connection.assert_called_once_with("test_conn")
+ assert hook._base_url_initialized
+
def test_custom_adapter(self):
custom_adapter = HTTPAdapter()
hook = HttpHook(method="GET", adapter=custom_adapter)