From d103055b11bd006756f511af962a69f6c5ffca8f Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Fri, 20 Sep 2024 10:44:43 +0200 Subject: [PATCH 1/9] Add Login RPC --- src/proto/flwr/proto/exec.proto | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/proto/flwr/proto/exec.proto b/src/proto/flwr/proto/exec.proto index ad0723c0480c..e7fd7fbcc311 100644 --- a/src/proto/flwr/proto/exec.proto +++ b/src/proto/flwr/proto/exec.proto @@ -26,6 +26,9 @@ service Exec { // Start log stream upon request rpc StreamLogs(StreamLogsRequest) returns (stream StreamLogsResponse) {} + + // Start login upon request + rpc Login(LoginRequest) returns (LoginResponse) {} } message StartRunRequest { @@ -36,3 +39,5 @@ message StartRunRequest { message StartRunResponse { uint64 run_id = 1; } message StreamLogsRequest { uint64 run_id = 1; } message StreamLogsResponse { string log_output = 1; } +message LoginRequest {} +message LoginResponse { string auth_url = 1; } From 3bbc21448acb2e3e4a927643667bfa0df0ebe443 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Fri, 20 Sep 2024 11:01:35 +0200 Subject: [PATCH 2/9] Generate updated proto --- src/py/flwr/proto/exec_pb2.py | 10 ++++++--- src/py/flwr/proto/exec_pb2.pyi | 17 +++++++++++++++ src/py/flwr/proto/exec_pb2_grpc.py | 34 +++++++++++++++++++++++++++++ src/py/flwr/proto/exec_pb2_grpc.pyi | 13 +++++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/py/flwr/proto/exec_pb2.py b/src/py/flwr/proto/exec_pb2.py index 574f39eaa18d..c922d262b84d 100644 --- a/src/py/flwr/proto/exec_pb2.py +++ b/src/py/flwr/proto/exec_pb2.py @@ -16,7 +16,7 @@ from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xdf\x02\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12L\n\x11\x66\x65\x64\x65ration_config\x18\x03 \x03(\x0b\x32\x31.flwr.proto.StartRunRequest.FederationConfigEntry\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\x1aK\n\x15\x46\x65\x64\x65rationConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"#\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"(\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t2\xa0\x01\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xdf\x02\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12L\n\x11\x66\x65\x64\x65ration_config\x18\x03 \x03(\x0b\x32\x31.flwr.proto.StartRunRequest.FederationConfigEntry\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\x1aK\n\x15\x46\x65\x64\x65rationConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"#\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"(\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\"\x0e\n\x0cLoginRequest\"!\n\rLoginResponse\x12\x10\n\x08\x61uth_url\x18\x01 \x01(\t2\xe0\x01\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12>\n\x05Login\x12\x18.flwr.proto.LoginRequest\x1a\x19.flwr.proto.LoginResponse\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -39,6 +39,10 @@ _globals['_STREAMLOGSREQUEST']._serialized_end=512 _globals['_STREAMLOGSRESPONSE']._serialized_start=514 _globals['_STREAMLOGSRESPONSE']._serialized_end=554 - _globals['_EXEC']._serialized_start=557 - _globals['_EXEC']._serialized_end=717 + _globals['_LOGINREQUEST']._serialized_start=556 + _globals['_LOGINREQUEST']._serialized_end=570 + _globals['_LOGINRESPONSE']._serialized_start=572 + _globals['_LOGINRESPONSE']._serialized_end=605 + _globals['_EXEC']._serialized_start=608 + _globals['_EXEC']._serialized_end=832 # @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/exec_pb2.pyi b/src/py/flwr/proto/exec_pb2.pyi index 8b7e07c8875f..ff01e36d581c 100644 --- a/src/py/flwr/proto/exec_pb2.pyi +++ b/src/py/flwr/proto/exec_pb2.pyi @@ -96,3 +96,20 @@ class StreamLogsResponse(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["log_output",b"log_output"]) -> None: ... global___StreamLogsResponse = StreamLogsResponse + +class LoginRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + def __init__(self, + ) -> None: ... +global___LoginRequest = LoginRequest + +class LoginResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + AUTH_URL_FIELD_NUMBER: builtins.int + auth_url: typing.Text + def __init__(self, + *, + auth_url: typing.Text = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["auth_url",b"auth_url"]) -> None: ... +global___LoginResponse = LoginResponse diff --git a/src/py/flwr/proto/exec_pb2_grpc.py b/src/py/flwr/proto/exec_pb2_grpc.py index 8cf4ce52a300..265897b51053 100644 --- a/src/py/flwr/proto/exec_pb2_grpc.py +++ b/src/py/flwr/proto/exec_pb2_grpc.py @@ -24,6 +24,11 @@ def __init__(self, channel): request_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.SerializeToString, response_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString, ) + self.Login = channel.unary_unary( + '/flwr.proto.Exec/Login', + request_serializer=flwr_dot_proto_dot_exec__pb2.LoginRequest.SerializeToString, + response_deserializer=flwr_dot_proto_dot_exec__pb2.LoginResponse.FromString, + ) class ExecServicer(object): @@ -43,6 +48,13 @@ def StreamLogs(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def Login(self, request, context): + """Start login upon request + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_ExecServicer_to_server(servicer, server): rpc_method_handlers = { @@ -56,6 +68,11 @@ def add_ExecServicer_to_server(servicer, server): request_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.FromString, response_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.SerializeToString, ), + 'Login': grpc.unary_unary_rpc_method_handler( + servicer.Login, + request_deserializer=flwr_dot_proto_dot_exec__pb2.LoginRequest.FromString, + response_serializer=flwr_dot_proto_dot_exec__pb2.LoginResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'flwr.proto.Exec', rpc_method_handlers) @@ -99,3 +116,20 @@ def StreamLogs(request, flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Login(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/flwr.proto.Exec/Login', + flwr_dot_proto_dot_exec__pb2.LoginRequest.SerializeToString, + flwr_dot_proto_dot_exec__pb2.LoginResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/py/flwr/proto/exec_pb2_grpc.pyi b/src/py/flwr/proto/exec_pb2_grpc.pyi index 20da3a53f4a8..4e61cf27712c 100644 --- a/src/py/flwr/proto/exec_pb2_grpc.pyi +++ b/src/py/flwr/proto/exec_pb2_grpc.pyi @@ -19,6 +19,11 @@ class ExecStub: flwr.proto.exec_pb2.StreamLogsResponse] """Start log stream upon request""" + Login: grpc.UnaryUnaryMultiCallable[ + flwr.proto.exec_pb2.LoginRequest, + flwr.proto.exec_pb2.LoginResponse] + """Start login upon request""" + class ExecServicer(metaclass=abc.ABCMeta): @abc.abstractmethod @@ -37,5 +42,13 @@ class ExecServicer(metaclass=abc.ABCMeta): """Start log stream upon request""" pass + @abc.abstractmethod + def Login(self, + request: flwr.proto.exec_pb2.LoginRequest, + context: grpc.ServicerContext, + ) -> flwr.proto.exec_pb2.LoginResponse: + """Start login upon request""" + pass + def add_ExecServicer_to_server(servicer: ExecServicer, server: grpc.Server) -> None: ... From f7f06aaedc7becbc3fbd8b71d25f92ade0e56910 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Fri, 20 Sep 2024 11:29:11 +0200 Subject: [PATCH 3/9] Add login servicer --- src/py/flwr/superexec/exec_servicer.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py index ebb12b5ddbd2..f7844d21ab32 100644 --- a/src/py/flwr/superexec/exec_servicer.py +++ b/src/py/flwr/superexec/exec_servicer.py @@ -33,6 +33,8 @@ StartRunResponse, StreamLogsRequest, StreamLogsResponse, + LoginRequest, + LoginResponse, ) from .executor import Executor, RunTracker @@ -101,6 +103,10 @@ def StreamLogs( # pylint: disable=C0103 time.sleep(1.0) # Sleep briefly to avoid busy waiting + def Login(self, request, context): + """Start login upon request + """ + def _capture_logs( run: RunTracker, From da31e25bdfcdab4c60976c5ebcbd10766d66ce62 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Fri, 20 Sep 2024 11:29:52 +0200 Subject: [PATCH 4/9] Format --- src/py/flwr/superexec/exec_servicer.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py index f7844d21ab32..f0c18b843285 100644 --- a/src/py/flwr/superexec/exec_servicer.py +++ b/src/py/flwr/superexec/exec_servicer.py @@ -29,12 +29,12 @@ from flwr.common.serde import user_config_from_proto from flwr.proto import exec_pb2_grpc # pylint: disable=E0611 from flwr.proto.exec_pb2 import ( # pylint: disable=E0611 + LoginRequest, + LoginResponse, StartRunRequest, StartRunResponse, StreamLogsRequest, StreamLogsResponse, - LoginRequest, - LoginResponse, ) from .executor import Executor, RunTracker @@ -104,8 +104,7 @@ def StreamLogs( # pylint: disable=C0103 time.sleep(1.0) # Sleep briefly to avoid busy waiting def Login(self, request, context): - """Start login upon request - """ + """Start login upon request.""" def _capture_logs( From 211bc3ac0bf90e3263c496de47da5070bfd4a016 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Fri, 20 Sep 2024 11:58:49 +0200 Subject: [PATCH 5/9] Format --- src/py/flwr/superexec/exec_servicer.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py index f0c18b843285..af74191ab6ac 100644 --- a/src/py/flwr/superexec/exec_servicer.py +++ b/src/py/flwr/superexec/exec_servicer.py @@ -103,8 +103,13 @@ def StreamLogs( # pylint: disable=C0103 time.sleep(1.0) # Sleep briefly to avoid busy waiting - def Login(self, request, context): - """Start login upon request.""" + def Login( + self, request: LoginRequest, context: grpc.ServicerContext + ) -> LoginResponse: + """Start login.""" + log(INFO, "ExecServicer.Login") + + return LoginResponse(auth_url="") def _capture_logs( From 7fe6a39bca5d72b37ce5c84d25d2dfaaa1390e56 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Sun, 24 Nov 2024 20:23:55 +0100 Subject: [PATCH 6/9] Format --- src/proto/flwr/proto/exec.proto | 12 +++--------- src/py/flwr/superexec/exec_servicer.py | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/proto/flwr/proto/exec.proto b/src/proto/flwr/proto/exec.proto index b3c486e00bba..584646cd664a 100644 --- a/src/proto/flwr/proto/exec.proto +++ b/src/proto/flwr/proto/exec.proto @@ -59,13 +59,7 @@ message ListRunsResponse { } message LoginRequest {} -message LoginResponse { - map login_details = 1; -} +message LoginResponse { map login_details = 1; } -message GetAuthTokenRequest { - map auth_details = 1; -} -message GetAuthTokenResponse { - map auth_tokens = 1; -} +message GetAuthTokenRequest { map auth_details = 1; } +message GetAuthTokenResponse { map auth_tokens = 1; } diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py index 7db6b320a316..85a868edc23e 100644 --- a/src/py/flwr/superexec/exec_servicer.py +++ b/src/py/flwr/superexec/exec_servicer.py @@ -162,4 +162,4 @@ def _create_list_runs_response(run_ids: set[int], state: LinkState) -> ListRunsR return ListRunsResponse( run_dict={run_id: run_to_proto(run) for run_id, run in run_dict.items() if run}, now=now().isoformat(), - ) \ No newline at end of file + ) From f8d6b2cc5ec9cc17b0774db4689e7527648fa4a6 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Sun, 24 Nov 2024 21:21:37 +0100 Subject: [PATCH 7/9] Format --- src/py/flwr/superexec/exec_servicer.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py index 85a868edc23e..548a6c222a5a 100644 --- a/src/py/flwr/superexec/exec_servicer.py +++ b/src/py/flwr/superexec/exec_servicer.py @@ -23,7 +23,6 @@ import grpc from flwr.common import now -from flwr.common.auth_plugin import ExecAuthPlugin from flwr.common.constant import LOG_STREAM_INTERVAL, Status from flwr.common.logger import log from flwr.common.serde import ( @@ -58,13 +57,11 @@ def __init__( linkstate_factory: LinkStateFactory, ffs_factory: FfsFactory, executor: Executor, - auth_plugin: Optional[ExecAuthPlugin] = None, ) -> None: self.linkstate_factory = linkstate_factory self.ffs_factory = ffs_factory self.executor = executor self.executor.initialize(linkstate_factory, ffs_factory) - self.auth_plugin = auth_plugin def StartRun( self, request: StartRunRequest, context: grpc.ServicerContext From 158677fb0d7f65ac0f7ebfb2c865d661b51287d8 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Sun, 24 Nov 2024 21:27:19 +0100 Subject: [PATCH 8/9] Format --- src/py/flwr/superexec/exec_servicer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py index 548a6c222a5a..e2fe9687641b 100644 --- a/src/py/flwr/superexec/exec_servicer.py +++ b/src/py/flwr/superexec/exec_servicer.py @@ -18,7 +18,7 @@ import time from collections.abc import Generator from logging import ERROR, INFO -from typing import Any, Optional +from typing import Any import grpc From 8e874a4ee760d66d8265a57675d053fcc6a05ab0 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Sun, 24 Nov 2024 21:35:37 +0100 Subject: [PATCH 9/9] Format --- src/py/flwr/superexec/exec_servicer.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py index e2fe9687641b..1867c7bcfa34 100644 --- a/src/py/flwr/superexec/exec_servicer.py +++ b/src/py/flwr/superexec/exec_servicer.py @@ -135,22 +135,14 @@ def Login( ) -> LoginResponse: """Start login.""" log(INFO, "ExecServicer.Login") - - context.abort( - grpc.StatusCode.UNIMPLEMENTED, - "SuperExec initialized without user authentication", - ) + return LoginResponse(login_details={}) def GetAuthToken( self, request: GetAuthTokenRequest, context: grpc.ServicerContext ) -> GetAuthTokenResponse: """Get auth token.""" log(INFO, "ExecServicer.GetAuthToken") - - context.abort( - grpc.StatusCode.UNIMPLEMENTED, - "SuperExec initialized without user authentication", - ) + return GetAuthTokenResponse(auth_tokens={}) def _create_list_runs_response(run_ids: set[int], state: LinkState) -> ListRunsResponse: