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 9207f9ba0f Change the URL building in HttpHookAsync to match the 
behavior of HttpHook (#37696)
9207f9ba0f is described below

commit 9207f9ba0f2e0b25d4319a66df1ca5d70bb8b6b5
Author: Alejo Rodriguez <54213247+alejorodrigue...@users.noreply.github.com>
AuthorDate: Mon Feb 26 09:18:40 2024 -0300

    Change the URL building in HttpHookAsync to match the behavior of HttpHook 
(#37696)
    
    They are moved from airflow.models.datasets to airflow.datasets since
    the intention is to use them with Dataset, not DatasetModel. It is more
    natural for users to import from the latter module instead.
    
    A new (abstract) base class is added for the two classes, plus the OG
    Dataset class, to inherit from. This allows us to replace a few
    isinstance checks with simple molymorphism and make the logic a bit
    simpler.
    
    Co-authored-by: Tzu-ping Chung <uranu...@gmail.com>
    Co-authored-by: Wei Lee <weilee...@gmail.com>
    Co-authored-by: Jed Cunningham 
<66968678+jedcunning...@users.noreply.github.com>
---
 airflow/providers/http/hooks/http.py    | 19 +++++++++----------
 tests/providers/http/hooks/test_http.py | 22 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/airflow/providers/http/hooks/http.py 
b/airflow/providers/http/hooks/http.py
index 91c0d07c1b..8631a5b175 100644
--- a/airflow/providers/http/hooks/http.py
+++ b/airflow/providers/http/hooks/http.py
@@ -38,6 +38,13 @@ if TYPE_CHECKING:
     from airflow.models import Connection
 
 
+def _url_from_endpoint(base_url: str | None, endpoint: str | None) -> str:
+    """Combine base url with endpoint."""
+    if base_url and not base_url.endswith("/") and endpoint and not 
endpoint.startswith("/"):
+        return f"{base_url}/{endpoint}"
+    return (base_url or "") + (endpoint or "")
+
+
 class HttpHook(BaseHook):
     """Interact with HTTP servers.
 
@@ -158,7 +165,7 @@ class HttpHook(BaseHook):
 
         session = self.get_conn(headers)
 
-        url = self.url_from_endpoint(endpoint)
+        url = _url_from_endpoint(self.base_url, endpoint)
 
         if self.tcp_keep_alive:
             keep_alive_adapter = TCPKeepAliveAdapter(
@@ -261,12 +268,6 @@ class HttpHook(BaseHook):
         # TODO: remove ignore type when 
https://github.com/jd/tenacity/issues/428 is resolved
         return self._retry_obj(self.run, *args, **kwargs)  # type: ignore
 
-    def url_from_endpoint(self, endpoint: str | None) -> str:
-        """Combine base url with endpoint."""
-        if self.base_url and not self.base_url.endswith("/") and endpoint and 
not endpoint.startswith("/"):
-            return self.base_url + "/" + endpoint
-        return (self.base_url or "") + (endpoint or "")
-
     def test_connection(self):
         """Test HTTP Connection."""
         try:
@@ -357,9 +358,7 @@ class HttpAsyncHook(BaseHook):
         if headers:
             _headers.update(headers)
 
-        base_url = (self.base_url or "").rstrip("/")
-        endpoint = (endpoint or "").lstrip("/")
-        url = f"{base_url}/{endpoint}"
+        url = _url_from_endpoint(self.base_url, endpoint)
 
         async with aiohttp.ClientSession() as session:
             if self.method == "GET":
diff --git a/tests/providers/http/hooks/test_http.py 
b/tests/providers/http/hooks/test_http.py
index 7b093c66bb..ae1545a99e 100644
--- a/tests/providers/http/hooks/test_http.py
+++ b/tests/providers/http/hooks/test_http.py
@@ -648,3 +648,25 @@ class TestHttpAsyncHook:
             "max_redirects": 3,
         }
         assert actual == {"bearer": "test"}
+
+    @pytest.mark.asyncio
+    async def test_build_request_url_from_connection(self):
+        conn = get_airflow_connection()
+        schema = conn.schema or "http"  # default to http
+        with mock.patch("airflow.hooks.base.BaseHook.get_connection", 
side_effect=get_airflow_connection):
+            hook = HttpAsyncHook()
+            with mock.patch("aiohttp.ClientSession.post", 
new_callable=mock.AsyncMock) as mocked_function:
+                await hook.run("v1/test")
+                assert mocked_function.call_args.args[0] == 
f"{schema}://{conn.host}v1/test"
+
+    @pytest.mark.asyncio
+    async def test_build_request_url_from_endpoint_param(self):
+        def get_empty_conn(conn_id: str = "http_default"):
+            return Connection(conn_id=conn_id, conn_type="http")
+
+        hook = HttpAsyncHook()
+        with mock.patch("airflow.hooks.base.BaseHook.get_connection", 
side_effect=get_empty_conn), mock.patch(
+            "aiohttp.ClientSession.post", new_callable=mock.AsyncMock
+        ) as mocked_function:
+            await hook.run("test.com:8080/v1/test")
+            assert mocked_function.call_args.args[0] == 
"http://test.com:8080/v1/test";

Reply via email to