11# Copyright 2025 Intel Corporation
22# SPDX-License-Identifier: Apache-2.0
33
4+ import importlib
5+ import logging
6+
47from flwr .proto import grpcadapter_pb2
8+ from google .protobuf .message import DecodeError
59
610from openfl .protocols import aggregator_pb2
711
12+ logger = logging .getLogger (__name__ )
13+
814
915def 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