amoghrajesh commented on code in PR #58992:
URL: https://github.com/apache/airflow/pull/58992#discussion_r2588343602


##########
airflow-core/src/airflow/serialization/stringify.py:
##########
@@ -0,0 +1,131 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+from typing import Any, TypeVar
+
+T = TypeVar("T", bool, float, int, dict, list, str, tuple, set)
+
+CLASSNAME = "__classname__"
+VERSION = "__version__"
+DATA = "__data__"
+OLD_TYPE = "__type"
+OLD_DATA = "__var"
+OLD_DICT = "dict"
+DEFAULT_VERSION = 0
+
+_primitives = (int, bool, float, str)
+_builtin_collections = (frozenset, list, set, tuple)
+
+
+def _convert(old: dict) -> dict:
+    """Convert an old style serialization to new style."""
+    if OLD_TYPE in old and OLD_DATA in old:
+        # Return old style dicts directly as they do not need wrapping
+        if old[OLD_TYPE] == OLD_DICT:
+            return old[OLD_DATA]
+        return {CLASSNAME: old[OLD_TYPE], VERSION: DEFAULT_VERSION, DATA: 
old[OLD_DATA]}
+
+    return old
+
+
+def decode(d: dict[str, Any]) -> tuple[str, int, Any]:
+    """Extract classname, version, and data from a serialized dict."""
+    classname = d[CLASSNAME]
+    version = d[VERSION]
+
+    if not isinstance(classname, str) or not isinstance(version, int):
+        raise ValueError(f"cannot decode {d!r}")
+
+    data = d.get(DATA)
+
+    return classname, version, data
+
+
+def _stringify_builtin_collection(classname: str, value: Any):
+    if classname in ("builtins.tuple", "builtins.set", "builtins.frozenset"):
+        if isinstance(value, (list, tuple, set, frozenset)):
+            items = [str(stringify(v)) for v in value]
+            return f"({','.join(items)})"
+    return None
+
+
+def stringify(o: T | None) -> object:
+    """
+    Convert a serialized object to a human readable representation.
+
+    Matches the behavior of deserialize(full=False) exactly:
+    - Returns objects as-is for primitives, collections, plain dicts
+    - Only returns string when encountering a serialized object (__classname__)
+    """
+    if o is None:
+        return o
+
+    if isinstance(o, _primitives):
+        return o
+
+    # tuples, sets are included here for backwards compatibility
+    if isinstance(o, _builtin_collections):
+        col = [stringify(d) for d in o]
+        if isinstance(o, tuple):
+            return tuple(col)
+
+        if isinstance(o, set):
+            return set(col)
+
+        return col
+
+    if not isinstance(o, dict):
+        # if o is not a dict, then it's already deserialized
+        # in this case we should return it as is
+        return o
+
+    o = _convert(o)
+
+    # plain dict and no type hint
+    if CLASSNAME not in o or VERSION not in o:
+        return {str(k): stringify(v) for k, v in o.items()}
+
+    classname, version, value = decode(o)
+
+    if not classname:
+        raise TypeError("classname cannot be empty")
+
+    # Early detection for `airflow.` classes. These classes will need full 
deserialization, not just stringification
+    if isinstance(classname, str) and classname.startswith("airflow."):
+        raise ValueError(

Review Comment:
   And at that time, if it detects that is is trying to deser a `airflow.sdk` 
class, it fails this way: 
   ```python
   airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_xcom.py:221 
(TestGetXComEntry.test_stringify_false[nonjsonable])
   ../src/airflow/api_fastapi/core_api/routes/public/xcom.py:120: in 
get_xcom_entry
       item.value = stringify_xcom(parsed_value)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../src/airflow/serialization/stringify.py:111: in stringify
       raise ValueError(
   E   ValueError: Cannot stringify Airflow class 
'airflow.sdk.definitions.asset.AssetAlias'. Use XComModel.deserialize_value() 
to deserialize Airflow classes.
   
   During handling of the above exception, another exception occurred:
   ../src/airflow/utils/json.py:64: in __init__
       import airflow.sdk.serialization.serde  # noqa: F401
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../task-sdk/src/airflow/sdk/serialization/serde.py:409: in <module>
       _register()
   ../../task-sdk/src/airflow/sdk/serialization/serde.py:368: in _register
       for _, module_name, _ in 
iter_namespace(airflow.sdk.serialization.serializers):
                                               
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   E   AttributeError: module 'airflow.sdk.serialization' has no attribute 
'serializers'
   
   The above exception was the direct cause of the following exception:
   unit/api_fastapi/core_api/routes/public/test_xcom.py:235: in 
test_stringify_false
       response = test_client.get(url, params={"deserialize": True, 
"stringify": False})
                  
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/testclient.py:479: in get
       return super().get(
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:1053: in get
       return self.request(
   ../../.venv/lib/python3.13/site-packages/starlette/testclient.py:451: in 
request
       return super().request(
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:825: in request
       return self.send(request, auth=auth, follow_redirects=follow_redirects)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:914: in send
       response = self._send_handling_auth(
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:942: in 
_send_handling_auth
       response = self._send_handling_redirects(
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:979: in 
_send_handling_redirects
       response = self._send_single_request(request)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:1014: in 
_send_single_request
       response = transport.handle_request(request)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/testclient.py:354: in 
handle_request
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/testclient.py:351: in 
handle_request
       portal.call(self.app, scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/anyio/from_thread.py:291: in call
       return cast(T_Retval, self.start_task_soon(func, *args).result())
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/concurrent/futures/_base.py:456:
 in result
       return self.__get_result()
              ^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/concurrent/futures/_base.py:401:
 in __get_result
       raise self._exception
   ../../.venv/lib/python3.13/site-packages/anyio/from_thread.py:222: in 
_call_func
       retval = await retval_or_awaitable
                ^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/fastapi/applications.py:1134: in 
__call__
       await super().__call__(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/applications.py:113: in 
__call__
       await self.middleware_stack(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/errors.py:186: 
in __call__
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/errors.py:164: 
in __call__
       await self.app(scope, receive, _send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/gzip.py:29: in 
__call__
       await responder(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/gzip.py:130: 
in __call__
       await super().__call__(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/gzip.py:46: in 
__call__
       await self.app(scope, receive, self.send_with_compression)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/cors.py:85: in 
__call__
       await self.app(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:182: 
in __call__
       with recv_stream, send_stream, collapse_excgroups():
                                      ^^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py:162:
 in __exit__
       self.gen.throw(value)
   ../../.venv/lib/python3.13/site-packages/starlette/_utils.py:85: in 
collapse_excgroups
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:184: 
in __call__
       response = await self.dispatch_func(request, call_next)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../src/airflow/api_fastapi/auth/middlewares/refresh_token.py:51: in dispatch
       response = await call_next(request)
                  ^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:159: 
in call_next
       raise app_exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144: 
in coro
       await self.app(scope, receive_or_disconnect, send_no_error)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:182: 
in __call__
       with recv_stream, send_stream, collapse_excgroups():
                                      ^^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py:162:
 in __exit__
       self.gen.throw(value)
   ../../.venv/lib/python3.13/site-packages/starlette/_utils.py:85: in 
collapse_excgroups
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:184: 
in __call__
       response = await self.dispatch_func(request, call_next)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   unit/plugins/test_plugin.py:115: in dispatch
       return await call_next(request)
              ^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:159: 
in call_next
       raise app_exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144: 
in coro
       await self.app(scope, receive_or_disconnect, send_no_error)
   
../../.venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py:63: 
in __call__
       await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:53: 
in wrapped_app
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:42: 
in wrapped_app
       await app(scope, receive, sender)
   
../../.venv/lib/python3.13/site-packages/fastapi/middleware/asyncexitstack.py:18:
 in __call__
       await self.app(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/routing.py:716: in 
__call__
       await self.middleware_stack(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/routing.py:736: in app
       await route.handle(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/routing.py:290: in handle
       await self.app(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/fastapi/routing.py:125: in app
       await wrap_app_handling_exceptions(app, request)(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:53: 
in wrapped_app
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:42: 
in wrapped_app
       await app(scope, receive, sender)
   ../../.venv/lib/python3.13/site-packages/fastapi/routing.py:111: in app
       response = await f(request)
                  ^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/fastapi/routing.py:391: in app
       raw_response = await run_endpoint_function(
   ../../.venv/lib/python3.13/site-packages/fastapi/routing.py:292: in 
run_endpoint_function
       return await run_in_threadpool(dependant.call, **values)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/concurrency.py:38: in 
run_in_threadpool
       return await anyio.to_thread.run_sync(func)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/anyio/to_thread.py:56: in run_sync
       return await get_async_backend().run_sync_in_worker_thread(
   ../../.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py:2476: 
in run_sync_in_worker_thread
       return await future
              ^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py:967: in 
run
       result = context.run(func, *args)
                ^^^^^^^^^^^^^^^^^^^^^^^^
   ../src/airflow/api_fastapi/core_api/routes/public/xcom.py:122: in 
get_xcom_entry
       item.value = XComModel.deserialize_value(result)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../src/airflow/models/xcom.py:389: in deserialize_value
       return json.loads(result.value, cls=XComDecoder)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/json/__init__.py:359:
 in loads
       return cls(**kw).decode(s)
              ^^^^^^^^^
   ../src/airflow/utils/json.py:66: in __init__
       raise ImportError(
   E   ImportError: apache-airflow-task-sdk is required for XCom serialization. 
Install the package to use XcomDecoder.
   2025-12-04T09:59:12.734488Z [info     ] Filling up the DagBag from /dev/null 
[airflow.dag_processing.dagbag.DagBag]
   2025-12-04T09:59:12.743171Z [info     ] Creating ORM DAG for test-dag-id 
[airflow.dag_processing.collection]
   2025-12-04T09:59:12.742168Z [info     ] Sync 1 DAGs                    
[airflow.serialization.serialized_objects]
   2025-12-04T09:59:12.751668Z [info     ] Sync 1 DAGs                    
[airflow.serialization.serialized_objects]
   2025-12-04T09:59:12.787515Z [info     ] Some Airflow 2 plugins have been 
detected in your environment. Currently FAB provider does not support Python 
3.13, so you cannot use Airflow 2 plugins with Airflow 3 until FAB provider 
will be Python 3.13 compatible. [airflow.api_fastapi.core_api.app]
   FAILED [100%]
   airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_xcom.py:221 
(TestGetXComEntry.test_stringify_false[nested])
   ../src/airflow/api_fastapi/core_api/routes/public/xcom.py:120: in 
get_xcom_entry
       item.value = stringify_xcom(parsed_value)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../src/airflow/serialization/stringify.py:84: in stringify
       col = [stringify(d) for d in o]
              ^^^^^^^^^^^^
   ../src/airflow/serialization/stringify.py:111: in stringify
       raise ValueError(
   E   ValueError: Cannot stringify Airflow class 
'airflow.sdk.definitions.asset.AssetAlias'. Use XComModel.deserialize_value() 
to deserialize Airflow classes.
   
   During handling of the above exception, another exception occurred:
   ../src/airflow/utils/json.py:64: in __init__
       import airflow.sdk.serialization.serde  # noqa: F401
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../task-sdk/src/airflow/sdk/serialization/serde.py:409: in <module>
       _register()
   ../../task-sdk/src/airflow/sdk/serialization/serde.py:368: in _register
       for _, module_name, _ in 
iter_namespace(airflow.sdk.serialization.serializers):
                                               
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   E   AttributeError: module 'airflow.sdk.serialization' has no attribute 
'serializers'
   
   The above exception was the direct cause of the following exception:
   unit/api_fastapi/core_api/routes/public/test_xcom.py:235: in 
test_stringify_false
       response = test_client.get(url, params={"deserialize": True, 
"stringify": False})
                  
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/testclient.py:479: in get
       return super().get(
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:1053: in get
       return self.request(
   ../../.venv/lib/python3.13/site-packages/starlette/testclient.py:451: in 
request
       return super().request(
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:825: in request
       return self.send(request, auth=auth, follow_redirects=follow_redirects)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:914: in send
       response = self._send_handling_auth(
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:942: in 
_send_handling_auth
       response = self._send_handling_redirects(
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:979: in 
_send_handling_redirects
       response = self._send_single_request(request)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/httpx/_client.py:1014: in 
_send_single_request
       response = transport.handle_request(request)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/testclient.py:354: in 
handle_request
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/testclient.py:351: in 
handle_request
       portal.call(self.app, scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/anyio/from_thread.py:291: in call
       return cast(T_Retval, self.start_task_soon(func, *args).result())
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/concurrent/futures/_base.py:456:
 in result
       return self.__get_result()
              ^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/concurrent/futures/_base.py:401:
 in __get_result
       raise self._exception
   ../../.venv/lib/python3.13/site-packages/anyio/from_thread.py:222: in 
_call_func
       retval = await retval_or_awaitable
                ^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/fastapi/applications.py:1134: in 
__call__
       await super().__call__(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/applications.py:113: in 
__call__
       await self.middleware_stack(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/errors.py:186: 
in __call__
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/errors.py:164: 
in __call__
       await self.app(scope, receive, _send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/gzip.py:29: in 
__call__
       await responder(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/gzip.py:130: 
in __call__
       await super().__call__(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/gzip.py:46: in 
__call__
       await self.app(scope, receive, self.send_with_compression)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/cors.py:85: in 
__call__
       await self.app(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:182: 
in __call__
       with recv_stream, send_stream, collapse_excgroups():
                                      ^^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py:162:
 in __exit__
       self.gen.throw(value)
   ../../.venv/lib/python3.13/site-packages/starlette/_utils.py:85: in 
collapse_excgroups
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:184: 
in __call__
       response = await self.dispatch_func(request, call_next)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../src/airflow/api_fastapi/auth/middlewares/refresh_token.py:51: in dispatch
       response = await call_next(request)
                  ^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:159: 
in call_next
       raise app_exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144: 
in coro
       await self.app(scope, receive_or_disconnect, send_no_error)
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:182: 
in __call__
       with recv_stream, send_stream, collapse_excgroups():
                                      ^^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py:162:
 in __exit__
       self.gen.throw(value)
   ../../.venv/lib/python3.13/site-packages/starlette/_utils.py:85: in 
collapse_excgroups
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:184: 
in __call__
       response = await self.dispatch_func(request, call_next)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   unit/plugins/test_plugin.py:115: in dispatch
       return await call_next(request)
              ^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:159: 
in call_next
       raise app_exc
   ../../.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144: 
in coro
       await self.app(scope, receive_or_disconnect, send_no_error)
   
../../.venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py:63: 
in __call__
       await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:53: 
in wrapped_app
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:42: 
in wrapped_app
       await app(scope, receive, sender)
   
../../.venv/lib/python3.13/site-packages/fastapi/middleware/asyncexitstack.py:18:
 in __call__
       await self.app(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/routing.py:716: in 
__call__
       await self.middleware_stack(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/routing.py:736: in app
       await route.handle(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/routing.py:290: in handle
       await self.app(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/fastapi/routing.py:125: in app
       await wrap_app_handling_exceptions(app, request)(scope, receive, send)
   ../../.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:53: 
in wrapped_app
       raise exc
   ../../.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:42: 
in wrapped_app
       await app(scope, receive, sender)
   ../../.venv/lib/python3.13/site-packages/fastapi/routing.py:111: in app
       response = await f(request)
                  ^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/fastapi/routing.py:391: in app
       raw_response = await run_endpoint_function(
   ../../.venv/lib/python3.13/site-packages/fastapi/routing.py:292: in 
run_endpoint_function
       return await run_in_threadpool(dependant.call, **values)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/starlette/concurrency.py:38: in 
run_in_threadpool
       return await anyio.to_thread.run_sync(func)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/anyio/to_thread.py:56: in run_sync
       return await get_async_backend().run_sync_in_worker_thread(
   ../../.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py:2476: 
in run_sync_in_worker_thread
       return await future
              ^^^^^^^^^^^^
   ../../.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py:967: in 
run
       result = context.run(func, *args)
                ^^^^^^^^^^^^^^^^^^^^^^^^
   ../src/airflow/api_fastapi/core_api/routes/public/xcom.py:122: in 
get_xcom_entry
       item.value = XComModel.deserialize_value(result)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ../src/airflow/models/xcom.py:389: in deserialize_value
       return json.loads(result.value, cls=XComDecoder)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   
/opt/homebrew/Cellar/[email protected]/3.13.3_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/json/__init__.py:359:
 in loads
       return cls(**kw).decode(s)
              ^^^^^^^^^
   ../src/airflow/utils/json.py:66: in __init__
       raise ImportError(
   E   ImportError: apache-airflow-task-sdk is required for XCom serialization. 
Install the package to use XcomDecoder.
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to