diff --git a/src/proto/flwr/proto/clientappio.proto b/src/proto/flwr/proto/clientappio.proto index 19d2db50501a..ee492a5acf6a 100644 --- a/src/proto/flwr/proto/clientappio.proto +++ b/src/proto/flwr/proto/clientappio.proto @@ -18,14 +18,13 @@ syntax = "proto3"; package flwr.proto; import "flwr/proto/fab.proto"; -import "flwr/proto/run.proto"; import "flwr/proto/message.proto"; service ClientAppIo { // Get token rpc GetToken(GetTokenRequest) returns (GetTokenResponse) {} - // Get Message, Context, and Run + // Get Message, Context, and Fab rpc PullClientAppInputs(PullClientAppInputsRequest) returns (PullClientAppInputsResponse) {} @@ -51,8 +50,7 @@ message PullClientAppInputsRequest { uint64 token = 1; } message PullClientAppInputsResponse { Message message = 1; Context context = 2; - Run run = 3; - Fab fab = 4; + Fab fab = 3; } message PushClientAppOutputsRequest { diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index e803eaf88864..3732fc9ecd81 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -496,7 +496,6 @@ def _on_backoff(retry_state: RetryState) -> None: clientapp_input=ClientAppInputs( message=message, context=context, - run=run, fab=fab, token=token, ), diff --git a/src/py/flwr/client/clientapp/app.py b/src/py/flwr/client/clientapp/app.py index 97eb36c4a411..1321dfc5e135 100644 --- a/src/py/flwr/client/clientapp/app.py +++ b/src/py/flwr/client/clientapp/app.py @@ -21,6 +21,7 @@ import grpc +from flwr.cli.config_utils import get_fab_metadata from flwr.cli.install import install_from_fab from flwr.client.client_app import ClientApp, LoadClientAppError from flwr.common import Context, Message @@ -34,9 +35,8 @@ fab_from_proto, message_from_proto, message_to_proto, - run_from_proto, ) -from flwr.common.typing import Fab, Run +from flwr.common.typing import Fab # pylint: disable=E0611 from flwr.proto.clientappio_pb2 import ( @@ -115,13 +115,14 @@ def run_clientapp( # pylint: disable=R0914 token = get_token(stub) time.sleep(1) - # Pull Message, Context, Run and (optional) FAB from SuperNode - message, context, run, fab = pull_message(stub=stub, token=token) + # Pull Message, Context, and (optional) FAB from SuperNode + message, context, fab = pull_message(stub=stub, token=token) # Install FAB, if provided if fab: log(DEBUG, "Flower ClientApp starts FAB installation.") install_from_fab(fab.content, flwr_dir=None, skip_prompt=True) + fab_id, fab_version = get_fab_metadata(fab.content) load_client_app_fn = get_load_client_app_fn( default_app_ref="", @@ -133,7 +134,7 @@ def run_clientapp( # pylint: disable=R0914 try: # Load ClientApp client_app: ClientApp = load_client_app_fn( - run.fab_id, run.fab_version, fab.hash_str if fab else "" + fab_id, fab_version, fab.hash_str if fab else "" ) # Execute ClientApp @@ -197,7 +198,7 @@ def get_token(stub: grpc.Channel) -> Optional[int]: def pull_message( stub: grpc.Channel, token: int -) -> tuple[Message, Context, Run, Optional[Fab]]: +) -> tuple[Message, Context, Optional[Fab]]: """Pull message from SuperNode to ClientApp.""" log(INFO, "Pulling ClientAppInputs for token %s", token) try: @@ -206,9 +207,8 @@ def pull_message( ) message = message_from_proto(res.message) context = context_from_proto(res.context) - run = run_from_proto(res.run) fab = fab_from_proto(res.fab) if res.fab else None - return message, context, run, fab + return message, context, fab except grpc.RpcError as e: log(ERROR, "[PullClientAppInputs] gRPC error occurred: %s", str(e)) raise e diff --git a/src/py/flwr/client/clientapp/clientappio_servicer.py b/src/py/flwr/client/clientapp/clientappio_servicer.py index fe7ccd6e908f..31fba5b2a447 100644 --- a/src/py/flwr/client/clientapp/clientappio_servicer.py +++ b/src/py/flwr/client/clientapp/clientappio_servicer.py @@ -30,9 +30,8 @@ fab_to_proto, message_from_proto, message_to_proto, - run_to_proto, ) -from flwr.common.typing import Fab, Run +from flwr.common.typing import Fab # pylint: disable=E0611 from flwr.proto import clientappio_pb2_grpc @@ -52,7 +51,6 @@ class ClientAppInputs: message: Message context: Context - run: Run fab: Optional[Fab] token: int @@ -106,7 +104,7 @@ def GetToken( def PullClientAppInputs( self, request: PullClientAppInputsRequest, context: grpc.ServicerContext ) -> PullClientAppInputsResponse: - """Pull Message, Context, and Run.""" + """Pull Message, Context, and Fab.""" log(DEBUG, "ClientAppIo.PullClientAppInputs") # Fail if no ClientAppInputs are available @@ -137,7 +135,6 @@ def PullClientAppInputs( return PullClientAppInputsResponse( message=message_to_proto(clientapp_input.message), context=context_to_proto(clientapp_input.context), - run=run_to_proto(clientapp_input.run), fab=fab_to_proto(clientapp_input.fab) if clientapp_input.fab else None, ) diff --git a/src/py/flwr/client/clientapp/clientappio_servicer_test.py b/src/py/flwr/client/clientapp/clientappio_servicer_test.py index 82c9f16e8201..10af8c90e502 100644 --- a/src/py/flwr/client/clientapp/clientappio_servicer_test.py +++ b/src/py/flwr/client/clientapp/clientappio_servicer_test.py @@ -35,7 +35,6 @@ PushClientAppOutputsResponse, ) from flwr.proto.message_pb2 import Context as ProtoContext -from flwr.proto.run_pb2 import Run as ProtoRun from flwr.server.superlink.linkstate.utils import generate_rand_int_from_bytes from .clientappio_servicer import ClientAppInputs, ClientAppIoServicer, ClientAppOutputs @@ -71,19 +70,12 @@ def test_set_inputs(self) -> None: state=self.maker.recordset(2, 2, 1), run_config={"runconfig1": 6.1}, ) - run = typing.Run( - run_id=1, - fab_id="lorem", - fab_version="ipsum", - fab_hash="dolor", - override_config=self.maker.user_config(), - ) fab = typing.Fab( hash_str="abc123#$%", content=b"\xf3\xf5\xf8\x98", ) - client_input = ClientAppInputs(message, context, run, fab, 1) + client_input = ClientAppInputs(message, context, fab, 1) client_output = ClientAppOutputs(message, context) # Execute and assert @@ -157,13 +149,12 @@ def test_pull_clientapp_inputs(self) -> None: mock_response = PullClientAppInputsResponse( message=message_to_proto(mock_message), context=ProtoContext(node_id=123), - run=ProtoRun(run_id=61016, fab_id="mock/mock", fab_version="v1.0.0"), fab=fab_to_proto(mock_fab), ) self.mock_stub.PullClientAppInputs.return_value = mock_response # Execute - message, context, run, fab = pull_message(self.mock_stub, token=456) + message, context, fab = pull_message(self.mock_stub, token=456) # Assert self.mock_stub.PullClientAppInputs.assert_called_once() @@ -171,9 +162,6 @@ def test_pull_clientapp_inputs(self) -> None: self.assertEqual(len(message.content.metrics_records), 2) self.assertEqual(len(message.content.configs_records), 1) self.assertEqual(context.node_id, 123) - self.assertEqual(run.run_id, 61016) - self.assertEqual(run.fab_id, "mock/mock") - self.assertEqual(run.fab_version, "v1.0.0") if fab: self.assertEqual(fab.hash_str, mock_fab.hash_str) self.assertEqual(fab.content, mock_fab.content) diff --git a/src/py/flwr/proto/clientappio_pb2.py b/src/py/flwr/proto/clientappio_pb2.py index 3fdc9f8a6ece..f2be44e3b60f 100644 --- a/src/py/flwr/proto/clientappio_pb2.py +++ b/src/py/flwr/proto/clientappio_pb2.py @@ -13,33 +13,32 @@ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2 -from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2 from flwr.proto import message_pb2 as flwr_dot_proto_dot_message__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lwr/proto/clientappio.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x18\x66lwr/proto/message.proto\"W\n\x15\x43lientAppOutputStatus\x12-\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x1f.flwr.proto.ClientAppOutputCode\x12\x0f\n\x07message\x18\x02 \x01(\t\"\x11\n\x0fGetTokenRequest\"!\n\x10GetTokenResponse\x12\r\n\x05token\x18\x01 \x01(\x04\"+\n\x1aPullClientAppInputsRequest\x12\r\n\x05token\x18\x01 \x01(\x04\"\xa5\x01\n\x1bPullClientAppInputsResponse\x12$\n\x07message\x18\x01 \x01(\x0b\x32\x13.flwr.proto.Message\x12$\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x13.flwr.proto.Context\x12\x1c\n\x03run\x18\x03 \x01(\x0b\x32\x0f.flwr.proto.Run\x12\x1c\n\x03\x66\x61\x62\x18\x04 \x01(\x0b\x32\x0f.flwr.proto.Fab\"x\n\x1bPushClientAppOutputsRequest\x12\r\n\x05token\x18\x01 \x01(\x04\x12$\n\x07message\x18\x02 \x01(\x0b\x32\x13.flwr.proto.Message\x12$\n\x07\x63ontext\x18\x03 \x01(\x0b\x32\x13.flwr.proto.Context\"Q\n\x1cPushClientAppOutputsResponse\x12\x31\n\x06status\x18\x01 \x01(\x0b\x32!.flwr.proto.ClientAppOutputStatus*L\n\x13\x43lientAppOutputCode\x12\x0b\n\x07SUCCESS\x10\x00\x12\x15\n\x11\x44\x45\x41\x44LINE_EXCEEDED\x10\x01\x12\x11\n\rUNKNOWN_ERROR\x10\x02\x32\xad\x02\n\x0b\x43lientAppIo\x12G\n\x08GetToken\x12\x1b.flwr.proto.GetTokenRequest\x1a\x1c.flwr.proto.GetTokenResponse\"\x00\x12h\n\x13PullClientAppInputs\x12&.flwr.proto.PullClientAppInputsRequest\x1a\'.flwr.proto.PullClientAppInputsResponse\"\x00\x12k\n\x14PushClientAppOutputs\x12\'.flwr.proto.PushClientAppOutputsRequest\x1a(.flwr.proto.PushClientAppOutputsResponse\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lwr/proto/clientappio.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x18\x66lwr/proto/message.proto\"W\n\x15\x43lientAppOutputStatus\x12-\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x1f.flwr.proto.ClientAppOutputCode\x12\x0f\n\x07message\x18\x02 \x01(\t\"\x11\n\x0fGetTokenRequest\"!\n\x10GetTokenResponse\x12\r\n\x05token\x18\x01 \x01(\x04\"+\n\x1aPullClientAppInputsRequest\x12\r\n\x05token\x18\x01 \x01(\x04\"\x87\x01\n\x1bPullClientAppInputsResponse\x12$\n\x07message\x18\x01 \x01(\x0b\x32\x13.flwr.proto.Message\x12$\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x13.flwr.proto.Context\x12\x1c\n\x03\x66\x61\x62\x18\x03 \x01(\x0b\x32\x0f.flwr.proto.Fab\"x\n\x1bPushClientAppOutputsRequest\x12\r\n\x05token\x18\x01 \x01(\x04\x12$\n\x07message\x18\x02 \x01(\x0b\x32\x13.flwr.proto.Message\x12$\n\x07\x63ontext\x18\x03 \x01(\x0b\x32\x13.flwr.proto.Context\"Q\n\x1cPushClientAppOutputsResponse\x12\x31\n\x06status\x18\x01 \x01(\x0b\x32!.flwr.proto.ClientAppOutputStatus*L\n\x13\x43lientAppOutputCode\x12\x0b\n\x07SUCCESS\x10\x00\x12\x15\n\x11\x44\x45\x41\x44LINE_EXCEEDED\x10\x01\x12\x11\n\rUNKNOWN_ERROR\x10\x02\x32\xad\x02\n\x0b\x43lientAppIo\x12G\n\x08GetToken\x12\x1b.flwr.proto.GetTokenRequest\x1a\x1c.flwr.proto.GetTokenResponse\"\x00\x12h\n\x13PullClientAppInputs\x12&.flwr.proto.PullClientAppInputsRequest\x1a\'.flwr.proto.PullClientAppInputsResponse\"\x00\x12k\n\x14PushClientAppOutputs\x12\'.flwr.proto.PushClientAppOutputsRequest\x1a(.flwr.proto.PushClientAppOutputsResponse\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.clientappio_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _globals['_CLIENTAPPOUTPUTCODE']._serialized_start=675 - _globals['_CLIENTAPPOUTPUTCODE']._serialized_end=751 - _globals['_CLIENTAPPOUTPUTSTATUS']._serialized_start=114 - _globals['_CLIENTAPPOUTPUTSTATUS']._serialized_end=201 - _globals['_GETTOKENREQUEST']._serialized_start=203 - _globals['_GETTOKENREQUEST']._serialized_end=220 - _globals['_GETTOKENRESPONSE']._serialized_start=222 - _globals['_GETTOKENRESPONSE']._serialized_end=255 - _globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_start=257 - _globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_end=300 - _globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_start=303 - _globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_end=468 - _globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_start=470 - _globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_end=590 - _globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_start=592 - _globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_end=673 - _globals['_CLIENTAPPIO']._serialized_start=754 - _globals['_CLIENTAPPIO']._serialized_end=1055 + _globals['_CLIENTAPPOUTPUTCODE']._serialized_start=623 + _globals['_CLIENTAPPOUTPUTCODE']._serialized_end=699 + _globals['_CLIENTAPPOUTPUTSTATUS']._serialized_start=92 + _globals['_CLIENTAPPOUTPUTSTATUS']._serialized_end=179 + _globals['_GETTOKENREQUEST']._serialized_start=181 + _globals['_GETTOKENREQUEST']._serialized_end=198 + _globals['_GETTOKENRESPONSE']._serialized_start=200 + _globals['_GETTOKENRESPONSE']._serialized_end=233 + _globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_start=235 + _globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_end=278 + _globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_start=281 + _globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_end=416 + _globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_start=418 + _globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_end=538 + _globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_start=540 + _globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_end=621 + _globals['_CLIENTAPPIO']._serialized_start=702 + _globals['_CLIENTAPPIO']._serialized_end=1003 # @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/clientappio_pb2.pyi b/src/py/flwr/proto/clientappio_pb2.pyi index 53d376d58101..0fdd1da41ab2 100644 --- a/src/py/flwr/proto/clientappio_pb2.pyi +++ b/src/py/flwr/proto/clientappio_pb2.pyi @@ -5,7 +5,6 @@ isort:skip_file import builtins import flwr.proto.fab_pb2 import flwr.proto.message_pb2 -import flwr.proto.run_pb2 import google.protobuf.descriptor import google.protobuf.internal.enum_type_wrapper import google.protobuf.message @@ -77,25 +76,21 @@ class PullClientAppInputsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor MESSAGE_FIELD_NUMBER: builtins.int CONTEXT_FIELD_NUMBER: builtins.int - RUN_FIELD_NUMBER: builtins.int FAB_FIELD_NUMBER: builtins.int @property def message(self) -> flwr.proto.message_pb2.Message: ... @property def context(self) -> flwr.proto.message_pb2.Context: ... @property - def run(self) -> flwr.proto.run_pb2.Run: ... - @property def fab(self) -> flwr.proto.fab_pb2.Fab: ... def __init__(self, *, message: typing.Optional[flwr.proto.message_pb2.Message] = ..., context: typing.Optional[flwr.proto.message_pb2.Context] = ..., - run: typing.Optional[flwr.proto.run_pb2.Run] = ..., fab: typing.Optional[flwr.proto.fab_pb2.Fab] = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["context",b"context","fab",b"fab","message",b"message","run",b"run"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["context",b"context","fab",b"fab","message",b"message","run",b"run"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["context",b"context","fab",b"fab","message",b"message"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["context",b"context","fab",b"fab","message",b"message"]) -> None: ... global___PullClientAppInputsResponse = PullClientAppInputsResponse class PushClientAppOutputsRequest(google.protobuf.message.Message): diff --git a/src/py/flwr/proto/clientappio_pb2_grpc.py b/src/py/flwr/proto/clientappio_pb2_grpc.py index 653d49fc1ead..a2a5d89a85ef 100644 --- a/src/py/flwr/proto/clientappio_pb2_grpc.py +++ b/src/py/flwr/proto/clientappio_pb2_grpc.py @@ -42,7 +42,7 @@ def GetToken(self, request, context): raise NotImplementedError('Method not implemented!') def PullClientAppInputs(self, request, context): - """Get Message, Context, and Run + """Get Message, Context, and Fab """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') diff --git a/src/py/flwr/proto/clientappio_pb2_grpc.pyi b/src/py/flwr/proto/clientappio_pb2_grpc.pyi index 3cddc769f745..e6bfc4e9776d 100644 --- a/src/py/flwr/proto/clientappio_pb2_grpc.pyi +++ b/src/py/flwr/proto/clientappio_pb2_grpc.pyi @@ -16,7 +16,7 @@ class ClientAppIoStub: PullClientAppInputs: grpc.UnaryUnaryMultiCallable[ flwr.proto.clientappio_pb2.PullClientAppInputsRequest, flwr.proto.clientappio_pb2.PullClientAppInputsResponse] - """Get Message, Context, and Run""" + """Get Message, Context, and Fab""" PushClientAppOutputs: grpc.UnaryUnaryMultiCallable[ flwr.proto.clientappio_pb2.PushClientAppOutputsRequest, @@ -38,7 +38,7 @@ class ClientAppIoServicer(metaclass=abc.ABCMeta): request: flwr.proto.clientappio_pb2.PullClientAppInputsRequest, context: grpc.ServicerContext, ) -> flwr.proto.clientappio_pb2.PullClientAppInputsResponse: - """Get Message, Context, and Run""" + """Get Message, Context, and Fab""" pass @abc.abstractmethod