This is an automated email from the ASF dual-hosted git repository.
jscheffl 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 991fb2f17b3 Remove Upper Pin package microsoft-kiota-abstractions
(#48461)
991fb2f17b3 is described below
commit 991fb2f17b3cf069af58a9bd8d72964cee4b6a7e
Author: Amol Saini <[email protected]>
AuthorDate: Sat Mar 29 21:19:12 2025 +0530
Remove Upper Pin package microsoft-kiota-abstractions (#48461)
* removed version pin
* updated provider dependencies
* mypy issue solved
* mypy issues resolved
* static issues fixed
* static issue fixed
* function argument type change
* string parsing issue solve
* mypy issue in test resolved..
* static issue solved
---
generated/provider_dependencies.json | 2 +-
providers/microsoft/azure/README.rst | 2 +-
providers/microsoft/azure/pyproject.toml | 2 +-
.../providers/microsoft/azure/get_provider_info.py | 2 +-
.../providers/microsoft/azure/hooks/msgraph.py | 52 +++++++++++-----------
.../providers/microsoft/azure/operators/msgraph.py | 4 +-
.../providers/microsoft/azure/sensors/msgraph.py | 4 +-
.../providers/microsoft/azure/triggers/msgraph.py | 4 +-
.../unit/microsoft/azure/hooks/test_msgraph.py | 22 ++++++++-
9 files changed, 56 insertions(+), 38 deletions(-)
diff --git a/generated/provider_dependencies.json
b/generated/provider_dependencies.json
index 7e9037af170..d115664ea66 100644
--- a/generated/provider_dependencies.json
+++ b/generated/provider_dependencies.json
@@ -875,7 +875,7 @@
"azure-storage-file-share>=12.7.0",
"azure-synapse-artifacts>=0.17.0",
"azure-synapse-spark>=0.2.0",
- "microsoft-kiota-abstractions<1.4.0",
+ "microsoft-kiota-abstractions>=1.4.0",
"microsoft-kiota-http>=1.3.0,!=1.3.4",
"microsoft-kiota-serialization-json==1.0.0",
"microsoft-kiota-serialization-text==1.0.0",
diff --git a/providers/microsoft/azure/README.rst
b/providers/microsoft/azure/README.rst
index 35d113fde9a..f59f258d174 100644
--- a/providers/microsoft/azure/README.rst
+++ b/providers/microsoft/azure/README.rst
@@ -79,7 +79,7 @@ PIP package Version required
``microsoft-kiota-http`` ``>=1.3.0,!=1.3.4``
``microsoft-kiota-serialization-json`` ``==1.0.0``
``microsoft-kiota-serialization-text`` ``==1.0.0``
-``microsoft-kiota-abstractions`` ``<1.4.0``
+``microsoft-kiota-abstractions`` ``>=1.4.0``
``msal-extensions`` ``>=1.1.0``
====================================== ===================
diff --git a/providers/microsoft/azure/pyproject.toml
b/providers/microsoft/azure/pyproject.toml
index fb70ee04fdc..f48c69d77f4 100644
--- a/providers/microsoft/azure/pyproject.toml
+++ b/providers/microsoft/azure/pyproject.toml
@@ -90,7 +90,7 @@ dependencies = [
"microsoft-kiota-serialization-text==1.0.0",
# microsoft-kiota-abstractions 1.4.0 breaks MyPy static checks on main
# see https://github.com/apache/airflow/issues/43036
- "microsoft-kiota-abstractions<1.4.0",
+ "microsoft-kiota-abstractions>=1.4.0",
"msal-extensions>=1.1.0",
]
diff --git
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/get_provider_info.py
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/get_provider_info.py
index 73e68c2f019..cb255cc274d 100644
---
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/get_provider_info.py
+++
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/get_provider_info.py
@@ -486,7 +486,7 @@ def get_provider_info():
"microsoft-kiota-http>=1.3.0,!=1.3.4",
"microsoft-kiota-serialization-json==1.0.0",
"microsoft-kiota-serialization-text==1.0.0",
- "microsoft-kiota-abstractions<1.4.0",
+ "microsoft-kiota-abstractions>=1.4.0",
"msal-extensions>=1.1.0",
],
"optional-dependencies": {
diff --git
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/hooks/msgraph.py
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/hooks/msgraph.py
index 45a3c8f2c6f..2a206aa749d 100644
---
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/hooks/msgraph.py
+++
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/hooks/msgraph.py
@@ -23,13 +23,12 @@ from contextlib import suppress
from http import HTTPStatus
from io import BytesIO
from json import JSONDecodeError
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING, Any, cast
from urllib.parse import quote, urljoin, urlparse
import httpx
from azure.identity import CertificateCredential, ClientSecretCredential
from httpx import AsyncHTTPTransport, Timeout
-from kiota_abstractions.api_error import APIError
from kiota_abstractions.method import Method
from kiota_abstractions.request_information import RequestInformation
from kiota_abstractions.response_handler import ResponseHandler
@@ -55,7 +54,7 @@ from airflow.hooks.base import BaseHook
if TYPE_CHECKING:
from azure.identity._internal.client_credential_base import
ClientCredentialBase
from kiota_abstractions.request_adapter import RequestAdapter
- from kiota_abstractions.request_information import QueryParams
+ from kiota_abstractions.request_information import QueryParameters
from kiota_abstractions.response_handler import NativeResponseType
from kiota_abstractions.serialization import ParsableFactory
from kiota_http.httpx_request_adapter import ResponseType
@@ -68,15 +67,16 @@ class DefaultResponseHandler(ResponseHandler):
@staticmethod
def get_value(response: NativeResponseType) -> Any:
+ response_casted = cast(httpx.Response, response)
with suppress(JSONDecodeError):
- return response.json()
- content = response.content
+ return response_casted.json()
+ content = response_casted.content
if not content:
- return {key: value for key, value in response.headers.items()}
+ return {key: value for key, value in
response_casted.headers.items()}
return content
async def handle_response_async(
- self, response: NativeResponseType, error_map: dict[str,
ParsableFactory | None] | None = None
+ self, response: NativeResponseType, error_map: dict[str,
ParsableFactory[Any]] | None
) -> Any:
"""
Invoke this callback method when a response is received.
@@ -84,10 +84,11 @@ class DefaultResponseHandler(ResponseHandler):
param response: The type of the native response object.
param error_map: The error dict to use in case of a failed request.
"""
- value = self.get_value(response)
- if response.status_code not in {200, 201, 202, 204, 302}:
- message = value or response.reason_phrase
- status_code = HTTPStatus(response.status_code)
+ response_casted = cast(httpx.Response, response) # Cast to
httpx.Response
+ value = self.get_value(response_casted)
+ if response_casted.status_code not in {200, 201, 202, 204, 302}:
+ message = value or response_casted.reason_phrase
+ status_code = HTTPStatus(response_casted.status_code)
if status_code == HTTPStatus.BAD_REQUEST:
raise AirflowBadRequest(message)
elif status_code == HTTPStatus.NOT_FOUND:
@@ -317,6 +318,8 @@ class KiotaRequestAdapterHook(BaseHook):
http_client=http_client,
base_url=base_url,
)
+ if request_adapter is None:
+ raise AirflowException("Failed to create the
HttpxRequestAdapter.")
self.cached_request_adapters[self.conn_id] = (api_version,
request_adapter)
self._api_version = api_version
return request_adapter
@@ -390,17 +393,17 @@ class KiotaRequestAdapterHook(BaseHook):
async def run(
self,
+ response_type: ResponseType,
url: str = "",
- response_type: ResponseType | None = None,
path_parameters: dict[str, Any] | None = None,
method: str = "GET",
- query_parameters: dict[str, QueryParams] | None = None,
+ query_parameters: dict[str, QueryParameters] | None = None,
headers: dict[str, str] | None = None,
data: dict[str, Any] | str | BytesIO | None = None,
):
self.log.info("Executing url '%s' as '%s'", url, method)
- response = await self.get_conn().send_primitive_async(
+ await self.get_conn().send_primitive_async(
request_info=self.request_information(
url=url,
response_type=response_type,
@@ -410,21 +413,17 @@ class KiotaRequestAdapterHook(BaseHook):
headers=headers,
data=data,
),
- response_type=response_type,
+ response_type=str(response_type),
error_map=self.error_mapping(),
)
- self.log.debug("response: %s", response)
-
- return response
-
def request_information(
self,
url: str,
response_type: ResponseType | None = None,
path_parameters: dict[str, Any] | None = None,
method: str = "GET",
- query_parameters: dict[str, QueryParams] | None = None,
+ query_parameters: dict[str, QueryParameters] | None = None,
headers: dict[str, str] | None = None,
data: dict[str, Any] | str | BytesIO | None = None,
) -> RequestInformation:
@@ -446,8 +445,12 @@ class KiotaRequestAdapterHook(BaseHook):
headers = {**self.DEFAULT_HEADERS, **headers} if headers else
self.DEFAULT_HEADERS
for header_name, header_value in headers.items():
request_information.headers.try_add(header_name=header_name,
header_value=header_value)
- if isinstance(data, BytesIO) or isinstance(data, bytes) or
isinstance(data, str):
+ if isinstance(data, BytesIO):
+ request_information.content = data.read()
+ elif isinstance(data, bytes):
request_information.content = data
+ elif isinstance(data, str):
+ request_information.content = data.encode("utf-8")
elif data:
request_information.headers.try_add(
header_name=RequestInformation.CONTENT_TYPE_HEADER,
header_value="application/json"
@@ -468,8 +471,5 @@ class KiotaRequestAdapterHook(BaseHook):
return {}
@staticmethod
- def error_mapping() -> dict[str, ParsableFactory | None]:
- return {
- "4XX": APIError,
- "5XX": APIError,
- }
+ def error_mapping() -> dict[str, type[ParsableFactory[Any]]] | None:
+ return {}
diff --git
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/operators/msgraph.py
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/operators/msgraph.py
index 459683a69f4..e5f88cadc4e 100644
---
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/operators/msgraph.py
+++
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/operators/msgraph.py
@@ -39,7 +39,7 @@ if TYPE_CHECKING:
from io import BytesIO
from kiota_abstractions.request_adapter import ResponseType
- from kiota_abstractions.request_information import QueryParams
+ from kiota_abstractions.request_information import QueryParameters
from msgraph_core import APIVersion
from airflow.utils.context import Context
@@ -122,7 +122,7 @@ class MSGraphAsyncOperator(BaseOperator):
path_parameters: dict[str, Any] | None = None,
url_template: str | None = None,
method: str = "GET",
- query_parameters: dict[str, QueryParams] | None = None,
+ query_parameters: dict[str, QueryParameters | object] | None = None,
headers: dict[str, str] | None = None,
data: dict[str, Any] | str | BytesIO | None = None,
conn_id: str = KiotaRequestAdapterHook.default_conn_name,
diff --git
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/sensors/msgraph.py
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/sensors/msgraph.py
index 39e728a9de1..86438ade146 100644
---
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/sensors/msgraph.py
+++
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/sensors/msgraph.py
@@ -31,7 +31,7 @@ if TYPE_CHECKING:
from datetime import timedelta
from io import BytesIO
- from kiota_abstractions.request_information import QueryParams
+ from kiota_abstractions.request_information import QueryParameters
from kiota_http.httpx_request_adapter import ResponseType
from msgraph_core import APIVersion
@@ -80,7 +80,7 @@ class MSGraphSensor(BaseSensorOperator):
path_parameters: dict[str, Any] | None = None,
url_template: str | None = None,
method: str = "GET",
- query_parameters: dict[str, QueryParams] | None = None,
+ query_parameters: dict[str, QueryParameters] | None = None,
headers: dict[str, str] | None = None,
data: dict[str, Any] | str | BytesIO | None = None,
conn_id: str = KiotaRequestAdapterHook.default_conn_name,
diff --git
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/triggers/msgraph.py
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/triggers/msgraph.py
index 4006ee6c3c0..e1faecdca9b 100644
---
a/providers/microsoft/azure/src/airflow/providers/microsoft/azure/triggers/msgraph.py
+++
b/providers/microsoft/azure/src/airflow/providers/microsoft/azure/triggers/msgraph.py
@@ -40,7 +40,7 @@ if TYPE_CHECKING:
from io import BytesIO
from kiota_abstractions.request_adapter import RequestAdapter
- from kiota_abstractions.request_information import QueryParams
+ from kiota_abstractions.request_information import QueryParameters
from kiota_http.httpx_request_adapter import ResponseType
from msgraph_core import APIVersion
@@ -116,7 +116,7 @@ class MSGraphTrigger(BaseTrigger):
path_parameters: dict[str, Any] | None = None,
url_template: str | None = None,
method: str = "GET",
- query_parameters: dict[str, QueryParams] | None = None,
+ query_parameters: dict[str, QueryParameters] | None = None,
headers: dict[str, str] | None = None,
data: dict[str, Any] | str | BytesIO | None = None,
conn_id: str = KiotaRequestAdapterHook.default_conn_name,
diff --git
a/providers/microsoft/azure/tests/unit/microsoft/azure/hooks/test_msgraph.py
b/providers/microsoft/azure/tests/unit/microsoft/azure/hooks/test_msgraph.py
index 9dc3a45452f..6304f773721 100644
--- a/providers/microsoft/azure/tests/unit/microsoft/azure/hooks/test_msgraph.py
+++ b/providers/microsoft/azure/tests/unit/microsoft/azure/hooks/test_msgraph.py
@@ -62,8 +62,26 @@ class TestKiotaRequestAdapterHook:
@staticmethod
def assert_tenant_id(request_adapter: RequestAdapter, expected_tenant_id:
str):
assert isinstance(request_adapter, HttpxRequestAdapter)
- tenant_id =
request_adapter._authentication_provider.access_token_provider._credentials._tenant_id
- assert tenant_id == expected_tenant_id
+
+ auth_provider = getattr(request_adapter, "_authentication_provider",
None)
+ if not auth_provider:
+ raise ValueError("Authentication provider is missing in the
request adapter")
+
+ access_token_provider = getattr(auth_provider,
"access_token_provider", None)
+ if not access_token_provider:
+ raise ValueError("Access token provider is missing in the
authentication provider")
+
+ credentials = getattr(access_token_provider, "_credentials", None)
+ if not credentials:
+ raise ValueError("Credentials object is missing in the access
token provider")
+
+ tenant_id = getattr(credentials, "_tenant_id", None)
+ if not tenant_id:
+ raise ValueError("Tenant ID is missing in credentials")
+
+ assert (
+ tenant_id == expected_tenant_id
+ ), f"Expected tenant ID '{expected_tenant_id}', but got '{tenant_id}'"
def test_get_conn(self):
with patch(