Skip to content

Commit 1101da3

Browse files
authored
Add function to deserialize the flower message for further introspection (#1649)
* add function to deserialize the flower message for further introspection Signed-off-by: kta-intel <[email protected]> * format Signed-off-by: kta-intel <[email protected]> --------- Signed-off-by: kta-intel <[email protected]>
1 parent 6576940 commit 1101da3

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

openfl/transport/grpc/interop/flower/message_conversion.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
# Copyright 2025 Intel Corporation
22
# SPDX-License-Identifier: Apache-2.0
33

4+
import importlib
5+
import logging
6+
47
from flwr.proto import grpcadapter_pb2
8+
from google.protobuf.message import DecodeError
59

610
from openfl.protocols import aggregator_pb2
711

12+
logger = logging.getLogger(__name__)
13+
814

915
def flower_to_openfl_message(flower_message, header=None, end_experiment=False):
1016
"""
@@ -28,6 +34,14 @@ def flower_to_openfl_message(flower_message, header=None, end_experiment=False):
2834
# If the input is already an OpenFL message, return it as-is
2935
return flower_message
3036
else:
37+
# Check if the Flower message can be deserialized, log a warning if not
38+
try:
39+
deserialized_message = deserialize_flower_message(flower_message)
40+
if deserialized_message is None:
41+
logger.warning("Failed to introspect Flower message.")
42+
except Exception as e:
43+
logger.warning(f"Exception during Flower message introspection: {e}")
44+
3145
# Create the OpenFL message
3246
openfl_message = aggregator_pb2.InteropMessage()
3347
# Set the MessageHeader fields based on the provided sender and receiver
@@ -67,3 +81,43 @@ def openfl_to_flower_message(openfl_message):
6781
flower_message = grpcadapter_pb2.MessageContainer()
6882
flower_message.ParseFromString(openfl_message.message.npbytes)
6983
return flower_message
84+
85+
86+
def deserialize_flower_message(flower_message):
87+
"""
88+
Deserialize the grpc_message_content of a Flower message using the module and class name
89+
specified in the metadata.
90+
91+
Args:
92+
flower_message: The Flower message containing the metadata and binary content.
93+
94+
Returns:
95+
The deserialized message object, or None if deserialization fails.
96+
"""
97+
# Access metadata directly
98+
metadata = flower_message.metadata
99+
module_name = metadata.get("grpc-message-module")
100+
qualname = metadata.get("grpc-message-qualname")
101+
102+
# Import the module
103+
try:
104+
module = importlib.import_module(module_name)
105+
except ImportError as e:
106+
print(f"Failed to import module: {module_name}. Error: {e}")
107+
return None
108+
109+
# Get the message class
110+
try:
111+
message_class = getattr(module, qualname)
112+
except AttributeError as e:
113+
print(f"Failed to get message class '{qualname}' from module '{module_name}'. Error: {e}")
114+
return None
115+
116+
# Deserialize the content
117+
try:
118+
message = message_class.FromString(flower_message.grpc_message_content)
119+
except DecodeError as e:
120+
print(f"Failed to deserialize message content. Error: {e}")
121+
return None
122+
123+
return message

0 commit comments

Comments
 (0)