flwr-nightly 1.20.0.dev20250617__py3-none-any.whl → 1.20.0.dev20250618__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flwr/proto/clientappio_pb2.py +27 -19
- flwr/proto/clientappio_pb2.pyi +47 -4
- flwr/proto/clientappio_pb2_grpc.py +70 -2
- flwr/proto/clientappio_pb2_grpc.pyi +30 -4
- flwr/supernode/cli/flwr_clientapp.py +8 -2
- flwr/supernode/runtime/run_clientapp.py +22 -18
- flwr/supernode/servicer/clientappio/clientappio_servicer.py +83 -85
- flwr/supernode/start_client_internal.py +22 -35
- {flwr_nightly-1.20.0.dev20250617.dist-info → flwr_nightly-1.20.0.dev20250618.dist-info}/METADATA +1 -1
- {flwr_nightly-1.20.0.dev20250617.dist-info → flwr_nightly-1.20.0.dev20250618.dist-info}/RECORD +12 -12
- {flwr_nightly-1.20.0.dev20250617.dist-info → flwr_nightly-1.20.0.dev20250618.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.20.0.dev20250617.dist-info → flwr_nightly-1.20.0.dev20250618.dist-info}/entry_points.txt +0 -0
flwr/proto/clientappio_pb2.py
CHANGED
@@ -17,29 +17,37 @@ from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
|
|
17
17
|
from flwr.proto import message_pb2 as flwr_dot_proto_dot_message__pb2
|
18
18
|
|
19
19
|
|
20
|
-
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(\
|
20
|
+
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\"%\n#GetRunIdsWithPendingMessagesRequest\"7\n$GetRunIdsWithPendingMessagesResponse\x12\x0f\n\x07run_ids\x18\x01 \x03(\x04\"%\n\x13RequestTokenRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"%\n\x14RequestTokenResponse\x12\r\n\x05token\x18\x01 \x01(\t\"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(\t\"\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(\t\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\x88\x04\n\x0b\x43lientAppIo\x12\x83\x01\n\x1cGetRunIdsWithPendingMessages\x12/.flwr.proto.GetRunIdsWithPendingMessagesRequest\x1a\x30.flwr.proto.GetRunIdsWithPendingMessagesResponse\"\x00\x12S\n\x0cRequestToken\x12\x1f.flwr.proto.RequestTokenRequest\x1a .flwr.proto.RequestTokenResponse\"\x00\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')
|
21
21
|
|
22
22
|
_globals = globals()
|
23
23
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
24
24
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.clientappio_pb2', _globals)
|
25
25
|
if _descriptor._USE_C_DESCRIPTORS == False:
|
26
26
|
DESCRIPTOR._options = None
|
27
|
-
_globals['_CLIENTAPPOUTPUTCODE']._serialized_start=
|
28
|
-
_globals['_CLIENTAPPOUTPUTCODE']._serialized_end=
|
29
|
-
_globals['
|
30
|
-
_globals['
|
31
|
-
_globals['
|
32
|
-
_globals['
|
33
|
-
_globals['
|
34
|
-
_globals['
|
35
|
-
_globals['
|
36
|
-
_globals['
|
37
|
-
_globals['
|
38
|
-
_globals['
|
39
|
-
_globals['
|
40
|
-
_globals['
|
41
|
-
_globals['
|
42
|
-
_globals['
|
43
|
-
_globals['
|
44
|
-
_globals['
|
27
|
+
_globals['_CLIENTAPPOUTPUTCODE']._serialized_start=849
|
28
|
+
_globals['_CLIENTAPPOUTPUTCODE']._serialized_end=925
|
29
|
+
_globals['_GETRUNIDSWITHPENDINGMESSAGESREQUEST']._serialized_start=114
|
30
|
+
_globals['_GETRUNIDSWITHPENDINGMESSAGESREQUEST']._serialized_end=151
|
31
|
+
_globals['_GETRUNIDSWITHPENDINGMESSAGESRESPONSE']._serialized_start=153
|
32
|
+
_globals['_GETRUNIDSWITHPENDINGMESSAGESRESPONSE']._serialized_end=208
|
33
|
+
_globals['_REQUESTTOKENREQUEST']._serialized_start=210
|
34
|
+
_globals['_REQUESTTOKENREQUEST']._serialized_end=247
|
35
|
+
_globals['_REQUESTTOKENRESPONSE']._serialized_start=249
|
36
|
+
_globals['_REQUESTTOKENRESPONSE']._serialized_end=286
|
37
|
+
_globals['_CLIENTAPPOUTPUTSTATUS']._serialized_start=288
|
38
|
+
_globals['_CLIENTAPPOUTPUTSTATUS']._serialized_end=375
|
39
|
+
_globals['_GETTOKENREQUEST']._serialized_start=377
|
40
|
+
_globals['_GETTOKENREQUEST']._serialized_end=394
|
41
|
+
_globals['_GETTOKENRESPONSE']._serialized_start=396
|
42
|
+
_globals['_GETTOKENRESPONSE']._serialized_end=429
|
43
|
+
_globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_start=431
|
44
|
+
_globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_end=474
|
45
|
+
_globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_start=477
|
46
|
+
_globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_end=642
|
47
|
+
_globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_start=644
|
48
|
+
_globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_end=764
|
49
|
+
_globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_start=766
|
50
|
+
_globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_end=847
|
51
|
+
_globals['_CLIENTAPPIO']._serialized_start=928
|
52
|
+
_globals['_CLIENTAPPIO']._serialized_end=1448
|
45
53
|
# @@protoc_insertion_point(module_scope)
|
flwr/proto/clientappio_pb2.pyi
CHANGED
@@ -7,6 +7,7 @@ import flwr.proto.fab_pb2
|
|
7
7
|
import flwr.proto.message_pb2
|
8
8
|
import flwr.proto.run_pb2
|
9
9
|
import google.protobuf.descriptor
|
10
|
+
import google.protobuf.internal.containers
|
10
11
|
import google.protobuf.internal.enum_type_wrapper
|
11
12
|
import google.protobuf.message
|
12
13
|
import typing
|
@@ -31,6 +32,48 @@ UNKNOWN_ERROR: ClientAppOutputCode.ValueType # 2
|
|
31
32
|
global___ClientAppOutputCode = ClientAppOutputCode
|
32
33
|
|
33
34
|
|
35
|
+
class GetRunIdsWithPendingMessagesRequest(google.protobuf.message.Message):
|
36
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
37
|
+
def __init__(self,
|
38
|
+
) -> None: ...
|
39
|
+
global___GetRunIdsWithPendingMessagesRequest = GetRunIdsWithPendingMessagesRequest
|
40
|
+
|
41
|
+
class GetRunIdsWithPendingMessagesResponse(google.protobuf.message.Message):
|
42
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
43
|
+
RUN_IDS_FIELD_NUMBER: builtins.int
|
44
|
+
@property
|
45
|
+
def run_ids(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]:
|
46
|
+
"""List of run IDs"""
|
47
|
+
pass
|
48
|
+
def __init__(self,
|
49
|
+
*,
|
50
|
+
run_ids: typing.Optional[typing.Iterable[builtins.int]] = ...,
|
51
|
+
) -> None: ...
|
52
|
+
def ClearField(self, field_name: typing_extensions.Literal["run_ids",b"run_ids"]) -> None: ...
|
53
|
+
global___GetRunIdsWithPendingMessagesResponse = GetRunIdsWithPendingMessagesResponse
|
54
|
+
|
55
|
+
class RequestTokenRequest(google.protobuf.message.Message):
|
56
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
57
|
+
RUN_ID_FIELD_NUMBER: builtins.int
|
58
|
+
run_id: builtins.int
|
59
|
+
def __init__(self,
|
60
|
+
*,
|
61
|
+
run_id: builtins.int = ...,
|
62
|
+
) -> None: ...
|
63
|
+
def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ...
|
64
|
+
global___RequestTokenRequest = RequestTokenRequest
|
65
|
+
|
66
|
+
class RequestTokenResponse(google.protobuf.message.Message):
|
67
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
68
|
+
TOKEN_FIELD_NUMBER: builtins.int
|
69
|
+
token: typing.Text
|
70
|
+
def __init__(self,
|
71
|
+
*,
|
72
|
+
token: typing.Text = ...,
|
73
|
+
) -> None: ...
|
74
|
+
def ClearField(self, field_name: typing_extensions.Literal["token",b"token"]) -> None: ...
|
75
|
+
global___RequestTokenResponse = RequestTokenResponse
|
76
|
+
|
34
77
|
class ClientAppOutputStatus(google.protobuf.message.Message):
|
35
78
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
36
79
|
CODE_FIELD_NUMBER: builtins.int
|
@@ -65,10 +108,10 @@ global___GetTokenResponse = GetTokenResponse
|
|
65
108
|
class PullClientAppInputsRequest(google.protobuf.message.Message):
|
66
109
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
67
110
|
TOKEN_FIELD_NUMBER: builtins.int
|
68
|
-
token:
|
111
|
+
token: typing.Text
|
69
112
|
def __init__(self,
|
70
113
|
*,
|
71
|
-
token:
|
114
|
+
token: typing.Text = ...,
|
72
115
|
) -> None: ...
|
73
116
|
def ClearField(self, field_name: typing_extensions.Literal["token",b"token"]) -> None: ...
|
74
117
|
global___PullClientAppInputsRequest = PullClientAppInputsRequest
|
@@ -103,14 +146,14 @@ class PushClientAppOutputsRequest(google.protobuf.message.Message):
|
|
103
146
|
TOKEN_FIELD_NUMBER: builtins.int
|
104
147
|
MESSAGE_FIELD_NUMBER: builtins.int
|
105
148
|
CONTEXT_FIELD_NUMBER: builtins.int
|
106
|
-
token:
|
149
|
+
token: typing.Text
|
107
150
|
@property
|
108
151
|
def message(self) -> flwr.proto.message_pb2.Message: ...
|
109
152
|
@property
|
110
153
|
def context(self) -> flwr.proto.message_pb2.Context: ...
|
111
154
|
def __init__(self,
|
112
155
|
*,
|
113
|
-
token:
|
156
|
+
token: typing.Text = ...,
|
114
157
|
message: typing.Optional[flwr.proto.message_pb2.Message] = ...,
|
115
158
|
context: typing.Optional[flwr.proto.message_pb2.Context] = ...,
|
116
159
|
) -> None: ...
|
@@ -14,6 +14,16 @@ class ClientAppIoStub(object):
|
|
14
14
|
Args:
|
15
15
|
channel: A grpc.Channel.
|
16
16
|
"""
|
17
|
+
self.GetRunIdsWithPendingMessages = channel.unary_unary(
|
18
|
+
'/flwr.proto.ClientAppIo/GetRunIdsWithPendingMessages',
|
19
|
+
request_serializer=flwr_dot_proto_dot_clientappio__pb2.GetRunIdsWithPendingMessagesRequest.SerializeToString,
|
20
|
+
response_deserializer=flwr_dot_proto_dot_clientappio__pb2.GetRunIdsWithPendingMessagesResponse.FromString,
|
21
|
+
)
|
22
|
+
self.RequestToken = channel.unary_unary(
|
23
|
+
'/flwr.proto.ClientAppIo/RequestToken',
|
24
|
+
request_serializer=flwr_dot_proto_dot_clientappio__pb2.RequestTokenRequest.SerializeToString,
|
25
|
+
response_deserializer=flwr_dot_proto_dot_clientappio__pb2.RequestTokenResponse.FromString,
|
26
|
+
)
|
17
27
|
self.GetToken = channel.unary_unary(
|
18
28
|
'/flwr.proto.ClientAppIo/GetToken',
|
19
29
|
request_serializer=flwr_dot_proto_dot_clientappio__pb2.GetTokenRequest.SerializeToString,
|
@@ -34,6 +44,20 @@ class ClientAppIoStub(object):
|
|
34
44
|
class ClientAppIoServicer(object):
|
35
45
|
"""Missing associated documentation comment in .proto file."""
|
36
46
|
|
47
|
+
def GetRunIdsWithPendingMessages(self, request, context):
|
48
|
+
"""Get run IDs with pending messages
|
49
|
+
"""
|
50
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
51
|
+
context.set_details('Method not implemented!')
|
52
|
+
raise NotImplementedError('Method not implemented!')
|
53
|
+
|
54
|
+
def RequestToken(self, request, context):
|
55
|
+
"""Request token
|
56
|
+
"""
|
57
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
58
|
+
context.set_details('Method not implemented!')
|
59
|
+
raise NotImplementedError('Method not implemented!')
|
60
|
+
|
37
61
|
def GetToken(self, request, context):
|
38
62
|
"""Get token
|
39
63
|
"""
|
@@ -42,14 +66,14 @@ class ClientAppIoServicer(object):
|
|
42
66
|
raise NotImplementedError('Method not implemented!')
|
43
67
|
|
44
68
|
def PullClientAppInputs(self, request, context):
|
45
|
-
"""
|
69
|
+
"""Pull client app inputs
|
46
70
|
"""
|
47
71
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
48
72
|
context.set_details('Method not implemented!')
|
49
73
|
raise NotImplementedError('Method not implemented!')
|
50
74
|
|
51
75
|
def PushClientAppOutputs(self, request, context):
|
52
|
-
"""
|
76
|
+
"""Push client app outputs
|
53
77
|
"""
|
54
78
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
55
79
|
context.set_details('Method not implemented!')
|
@@ -58,6 +82,16 @@ class ClientAppIoServicer(object):
|
|
58
82
|
|
59
83
|
def add_ClientAppIoServicer_to_server(servicer, server):
|
60
84
|
rpc_method_handlers = {
|
85
|
+
'GetRunIdsWithPendingMessages': grpc.unary_unary_rpc_method_handler(
|
86
|
+
servicer.GetRunIdsWithPendingMessages,
|
87
|
+
request_deserializer=flwr_dot_proto_dot_clientappio__pb2.GetRunIdsWithPendingMessagesRequest.FromString,
|
88
|
+
response_serializer=flwr_dot_proto_dot_clientappio__pb2.GetRunIdsWithPendingMessagesResponse.SerializeToString,
|
89
|
+
),
|
90
|
+
'RequestToken': grpc.unary_unary_rpc_method_handler(
|
91
|
+
servicer.RequestToken,
|
92
|
+
request_deserializer=flwr_dot_proto_dot_clientappio__pb2.RequestTokenRequest.FromString,
|
93
|
+
response_serializer=flwr_dot_proto_dot_clientappio__pb2.RequestTokenResponse.SerializeToString,
|
94
|
+
),
|
61
95
|
'GetToken': grpc.unary_unary_rpc_method_handler(
|
62
96
|
servicer.GetToken,
|
63
97
|
request_deserializer=flwr_dot_proto_dot_clientappio__pb2.GetTokenRequest.FromString,
|
@@ -83,6 +117,40 @@ def add_ClientAppIoServicer_to_server(servicer, server):
|
|
83
117
|
class ClientAppIo(object):
|
84
118
|
"""Missing associated documentation comment in .proto file."""
|
85
119
|
|
120
|
+
@staticmethod
|
121
|
+
def GetRunIdsWithPendingMessages(request,
|
122
|
+
target,
|
123
|
+
options=(),
|
124
|
+
channel_credentials=None,
|
125
|
+
call_credentials=None,
|
126
|
+
insecure=False,
|
127
|
+
compression=None,
|
128
|
+
wait_for_ready=None,
|
129
|
+
timeout=None,
|
130
|
+
metadata=None):
|
131
|
+
return grpc.experimental.unary_unary(request, target, '/flwr.proto.ClientAppIo/GetRunIdsWithPendingMessages',
|
132
|
+
flwr_dot_proto_dot_clientappio__pb2.GetRunIdsWithPendingMessagesRequest.SerializeToString,
|
133
|
+
flwr_dot_proto_dot_clientappio__pb2.GetRunIdsWithPendingMessagesResponse.FromString,
|
134
|
+
options, channel_credentials,
|
135
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
136
|
+
|
137
|
+
@staticmethod
|
138
|
+
def RequestToken(request,
|
139
|
+
target,
|
140
|
+
options=(),
|
141
|
+
channel_credentials=None,
|
142
|
+
call_credentials=None,
|
143
|
+
insecure=False,
|
144
|
+
compression=None,
|
145
|
+
wait_for_ready=None,
|
146
|
+
timeout=None,
|
147
|
+
metadata=None):
|
148
|
+
return grpc.experimental.unary_unary(request, target, '/flwr.proto.ClientAppIo/RequestToken',
|
149
|
+
flwr_dot_proto_dot_clientappio__pb2.RequestTokenRequest.SerializeToString,
|
150
|
+
flwr_dot_proto_dot_clientappio__pb2.RequestTokenResponse.FromString,
|
151
|
+
options, channel_credentials,
|
152
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
153
|
+
|
86
154
|
@staticmethod
|
87
155
|
def GetToken(request,
|
88
156
|
target,
|
@@ -8,6 +8,16 @@ import grpc
|
|
8
8
|
|
9
9
|
class ClientAppIoStub:
|
10
10
|
def __init__(self, channel: grpc.Channel) -> None: ...
|
11
|
+
GetRunIdsWithPendingMessages: grpc.UnaryUnaryMultiCallable[
|
12
|
+
flwr.proto.clientappio_pb2.GetRunIdsWithPendingMessagesRequest,
|
13
|
+
flwr.proto.clientappio_pb2.GetRunIdsWithPendingMessagesResponse]
|
14
|
+
"""Get run IDs with pending messages"""
|
15
|
+
|
16
|
+
RequestToken: grpc.UnaryUnaryMultiCallable[
|
17
|
+
flwr.proto.clientappio_pb2.RequestTokenRequest,
|
18
|
+
flwr.proto.clientappio_pb2.RequestTokenResponse]
|
19
|
+
"""Request token"""
|
20
|
+
|
11
21
|
GetToken: grpc.UnaryUnaryMultiCallable[
|
12
22
|
flwr.proto.clientappio_pb2.GetTokenRequest,
|
13
23
|
flwr.proto.clientappio_pb2.GetTokenResponse]
|
@@ -16,15 +26,31 @@ class ClientAppIoStub:
|
|
16
26
|
PullClientAppInputs: grpc.UnaryUnaryMultiCallable[
|
17
27
|
flwr.proto.clientappio_pb2.PullClientAppInputsRequest,
|
18
28
|
flwr.proto.clientappio_pb2.PullClientAppInputsResponse]
|
19
|
-
"""
|
29
|
+
"""Pull client app inputs"""
|
20
30
|
|
21
31
|
PushClientAppOutputs: grpc.UnaryUnaryMultiCallable[
|
22
32
|
flwr.proto.clientappio_pb2.PushClientAppOutputsRequest,
|
23
33
|
flwr.proto.clientappio_pb2.PushClientAppOutputsResponse]
|
24
|
-
"""
|
34
|
+
"""Push client app outputs"""
|
25
35
|
|
26
36
|
|
27
37
|
class ClientAppIoServicer(metaclass=abc.ABCMeta):
|
38
|
+
@abc.abstractmethod
|
39
|
+
def GetRunIdsWithPendingMessages(self,
|
40
|
+
request: flwr.proto.clientappio_pb2.GetRunIdsWithPendingMessagesRequest,
|
41
|
+
context: grpc.ServicerContext,
|
42
|
+
) -> flwr.proto.clientappio_pb2.GetRunIdsWithPendingMessagesResponse:
|
43
|
+
"""Get run IDs with pending messages"""
|
44
|
+
pass
|
45
|
+
|
46
|
+
@abc.abstractmethod
|
47
|
+
def RequestToken(self,
|
48
|
+
request: flwr.proto.clientappio_pb2.RequestTokenRequest,
|
49
|
+
context: grpc.ServicerContext,
|
50
|
+
) -> flwr.proto.clientappio_pb2.RequestTokenResponse:
|
51
|
+
"""Request token"""
|
52
|
+
pass
|
53
|
+
|
28
54
|
@abc.abstractmethod
|
29
55
|
def GetToken(self,
|
30
56
|
request: flwr.proto.clientappio_pb2.GetTokenRequest,
|
@@ -38,7 +64,7 @@ class ClientAppIoServicer(metaclass=abc.ABCMeta):
|
|
38
64
|
request: flwr.proto.clientappio_pb2.PullClientAppInputsRequest,
|
39
65
|
context: grpc.ServicerContext,
|
40
66
|
) -> flwr.proto.clientappio_pb2.PullClientAppInputsResponse:
|
41
|
-
"""
|
67
|
+
"""Pull client app inputs"""
|
42
68
|
pass
|
43
69
|
|
44
70
|
@abc.abstractmethod
|
@@ -46,7 +72,7 @@ class ClientAppIoServicer(metaclass=abc.ABCMeta):
|
|
46
72
|
request: flwr.proto.clientappio_pb2.PushClientAppOutputsRequest,
|
47
73
|
context: grpc.ServicerContext,
|
48
74
|
) -> flwr.proto.clientappio_pb2.PushClientAppOutputsResponse:
|
49
|
-
"""
|
75
|
+
"""Push client app outputs"""
|
50
76
|
pass
|
51
77
|
|
52
78
|
|
@@ -44,7 +44,7 @@ def flwr_clientapp() -> None:
|
|
44
44
|
)
|
45
45
|
run_clientapp(
|
46
46
|
clientappio_api_address=args.clientappio_api_address,
|
47
|
-
run_once=(args.token is not None),
|
47
|
+
run_once=(args.token is not None) or args.run_once,
|
48
48
|
token=args.token,
|
49
49
|
flwr_dir=args.flwr_dir,
|
50
50
|
certificates=None,
|
@@ -66,7 +66,7 @@ def _parse_args_run_flwr_clientapp() -> argparse.ArgumentParser:
|
|
66
66
|
)
|
67
67
|
parser.add_argument(
|
68
68
|
"--token",
|
69
|
-
type=
|
69
|
+
type=str,
|
70
70
|
required=False,
|
71
71
|
help="Unique token generated by SuperNode for each ClientApp execution",
|
72
72
|
)
|
@@ -77,5 +77,11 @@ def _parse_args_run_flwr_clientapp() -> argparse.ArgumentParser:
|
|
77
77
|
help="The PID of the parent process. When set, the process will terminate "
|
78
78
|
"when the parent process exits.",
|
79
79
|
)
|
80
|
+
parser.add_argument(
|
81
|
+
"--run-once",
|
82
|
+
action="store_true",
|
83
|
+
help="When set, this process will start a single ClientApp for a pending "
|
84
|
+
"message. If there is no pending message, the process will exit.",
|
85
|
+
)
|
80
86
|
add_args_flwr_app_common(parser=parser)
|
81
87
|
return parser
|
@@ -46,12 +46,14 @@ from flwr.common.typing import Fab, Run
|
|
46
46
|
|
47
47
|
# pylint: disable=E0611
|
48
48
|
from flwr.proto.clientappio_pb2 import (
|
49
|
-
|
50
|
-
|
49
|
+
GetRunIdsWithPendingMessagesRequest,
|
50
|
+
GetRunIdsWithPendingMessagesResponse,
|
51
51
|
PullClientAppInputsRequest,
|
52
52
|
PullClientAppInputsResponse,
|
53
53
|
PushClientAppOutputsRequest,
|
54
54
|
PushClientAppOutputsResponse,
|
55
|
+
RequestTokenRequest,
|
56
|
+
RequestTokenResponse,
|
55
57
|
)
|
56
58
|
from flwr.proto.clientappio_pb2_grpc import ClientAppIoStub
|
57
59
|
|
@@ -59,7 +61,7 @@ from flwr.proto.clientappio_pb2_grpc import ClientAppIoStub
|
|
59
61
|
def run_clientapp( # pylint: disable=R0913, R0914, R0917
|
60
62
|
clientappio_api_address: str,
|
61
63
|
run_once: bool,
|
62
|
-
token: Optional[
|
64
|
+
token: Optional[str] = None,
|
63
65
|
flwr_dir: Optional[str] = None,
|
64
66
|
certificates: Optional[bytes] = None,
|
65
67
|
parent_pid: Optional[int] = None,
|
@@ -84,9 +86,8 @@ def run_clientapp( # pylint: disable=R0913, R0914, R0917
|
|
84
86
|
|
85
87
|
while True:
|
86
88
|
# If token is not set, loop until token is received from SuperNode
|
87
|
-
|
89
|
+
if token is None:
|
88
90
|
token = get_token(stub)
|
89
|
-
time.sleep(1)
|
90
91
|
|
91
92
|
# Pull Message, Context, Run and (optional) FAB from SuperNode
|
92
93
|
message, context, run, fab = pull_clientappinputs(stub=stub, token=token)
|
@@ -172,23 +173,26 @@ def start_parent_process_monitor(
|
|
172
173
|
threading.Thread(target=monitor, daemon=True).start()
|
173
174
|
|
174
175
|
|
175
|
-
def get_token(stub:
|
176
|
+
def get_token(stub: ClientAppIoStub) -> str:
|
176
177
|
"""Get a token from SuperNode."""
|
177
178
|
log(DEBUG, "[flwr-clientapp] Request token")
|
178
|
-
|
179
|
-
res:
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
179
|
+
while True:
|
180
|
+
res: GetRunIdsWithPendingMessagesResponse = stub.GetRunIdsWithPendingMessages(
|
181
|
+
GetRunIdsWithPendingMessagesRequest()
|
182
|
+
)
|
183
|
+
|
184
|
+
for run_id in res.run_ids:
|
185
|
+
tk_res: RequestTokenResponse = stub.RequestToken(
|
186
|
+
RequestTokenRequest(run_id=run_id)
|
187
|
+
)
|
188
|
+
if tk_res.token:
|
189
|
+
return tk_res.token
|
190
|
+
|
191
|
+
time.sleep(1) # Wait before retrying to get run IDs
|
188
192
|
|
189
193
|
|
190
194
|
def pull_clientappinputs(
|
191
|
-
stub:
|
195
|
+
stub: ClientAppIoStub, token: str
|
192
196
|
) -> tuple[Message, Context, Run, Optional[Fab]]:
|
193
197
|
"""Pull ClientAppInputs from SuperNode."""
|
194
198
|
log(INFO, "[flwr-clientapp] Pull `ClientAppInputs` for token %s", token)
|
@@ -207,7 +211,7 @@ def pull_clientappinputs(
|
|
207
211
|
|
208
212
|
|
209
213
|
def push_clientappoutputs(
|
210
|
-
stub:
|
214
|
+
stub: ClientAppIoStub, token: str, message: Message, context: Context
|
211
215
|
) -> PushClientAppOutputsResponse:
|
212
216
|
"""Push ClientAppOutputs to SuperNode."""
|
213
217
|
log(INFO, "[flwr-clientapp] Push `ClientAppOutputs` for token %s", token)
|
@@ -37,13 +37,20 @@ from flwr.common.typing import Fab, Run
|
|
37
37
|
# pylint: disable=E0611
|
38
38
|
from flwr.proto import clientappio_pb2_grpc
|
39
39
|
from flwr.proto.clientappio_pb2 import ( # pylint: disable=E0401
|
40
|
+
GetRunIdsWithPendingMessagesRequest,
|
41
|
+
GetRunIdsWithPendingMessagesResponse,
|
40
42
|
GetTokenRequest,
|
41
43
|
GetTokenResponse,
|
42
44
|
PullClientAppInputsRequest,
|
43
45
|
PullClientAppInputsResponse,
|
44
46
|
PushClientAppOutputsRequest,
|
45
47
|
PushClientAppOutputsResponse,
|
48
|
+
RequestTokenRequest,
|
49
|
+
RequestTokenResponse,
|
46
50
|
)
|
51
|
+
from flwr.supercore.ffs import FfsFactory
|
52
|
+
from flwr.supercore.object_store import ObjectStoreFactory
|
53
|
+
from flwr.supernode.nodestate import NodeStateFactory
|
47
54
|
|
48
55
|
|
49
56
|
@dataclass
|
@@ -54,7 +61,6 @@ class ClientAppInputs:
|
|
54
61
|
context: Context
|
55
62
|
run: Run
|
56
63
|
fab: Optional[Fab]
|
57
|
-
token: int
|
58
64
|
|
59
65
|
|
60
66
|
@dataclass
|
@@ -69,11 +75,56 @@ class ClientAppOutputs:
|
|
69
75
|
class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
|
70
76
|
"""ClientAppIo API servicer."""
|
71
77
|
|
72
|
-
def __init__(
|
78
|
+
def __init__(
|
79
|
+
self,
|
80
|
+
state_factory: NodeStateFactory,
|
81
|
+
ffs_factory: FfsFactory,
|
82
|
+
objectstore_factory: ObjectStoreFactory,
|
83
|
+
) -> None:
|
84
|
+
self.state_factory = state_factory
|
85
|
+
self.ffs_factory = ffs_factory
|
86
|
+
self.objectstore_factory = objectstore_factory
|
87
|
+
|
73
88
|
self.clientapp_input: Optional[ClientAppInputs] = None
|
74
89
|
self.clientapp_output: Optional[ClientAppOutputs] = None
|
75
90
|
self.token_returned: bool = False
|
76
|
-
|
91
|
+
|
92
|
+
def GetRunIdsWithPendingMessages(
|
93
|
+
self,
|
94
|
+
request: GetRunIdsWithPendingMessagesRequest,
|
95
|
+
context: grpc.ServicerContext,
|
96
|
+
) -> GetRunIdsWithPendingMessagesResponse:
|
97
|
+
"""Get run IDs with pending messages."""
|
98
|
+
log(DEBUG, "ClientAppIo.GetRunIdsWithPendingMessages")
|
99
|
+
|
100
|
+
# Initialize state connection
|
101
|
+
state = self.state_factory.state()
|
102
|
+
|
103
|
+
# Get run IDs with pending messages
|
104
|
+
run_ids = state.get_run_ids_with_pending_messages()
|
105
|
+
|
106
|
+
# Return run IDs
|
107
|
+
return GetRunIdsWithPendingMessagesResponse(run_ids=run_ids)
|
108
|
+
|
109
|
+
def RequestToken(
|
110
|
+
self, request: RequestTokenRequest, context: grpc.ServicerContext
|
111
|
+
) -> RequestTokenResponse:
|
112
|
+
"""Request token."""
|
113
|
+
log(DEBUG, "ClientAppIo.RequestToken")
|
114
|
+
|
115
|
+
# Initialize state connection
|
116
|
+
state = self.state_factory.state()
|
117
|
+
|
118
|
+
# Attempt to create a token for the provided run ID
|
119
|
+
try:
|
120
|
+
token = state.create_token(request.run_id)
|
121
|
+
except ValueError:
|
122
|
+
# Return an empty token if A token already exists for this run ID,
|
123
|
+
# indicating the run is in progress
|
124
|
+
return RequestTokenResponse(token="")
|
125
|
+
|
126
|
+
# Return the token
|
127
|
+
return RequestTokenResponse(token=token)
|
77
128
|
|
78
129
|
def GetToken(
|
79
130
|
self, request: GetTokenRequest, context: grpc.ServicerContext
|
@@ -87,7 +138,6 @@ class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
|
|
87
138
|
grpc.StatusCode.FAILED_PRECONDITION,
|
88
139
|
"No inputs available.",
|
89
140
|
)
|
90
|
-
clientapp_input = cast(ClientAppInputs, self.clientapp_input)
|
91
141
|
|
92
142
|
# Fail if token was already returned in a previous call
|
93
143
|
if self.token_returned:
|
@@ -101,7 +151,7 @@ class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
|
|
101
151
|
# - token hasn't been returned before,
|
102
152
|
# return token
|
103
153
|
self.token_returned = True
|
104
|
-
return GetTokenResponse(token=
|
154
|
+
return GetTokenResponse(token=123) # To be deleted
|
105
155
|
|
106
156
|
def PullClientAppInputs(
|
107
157
|
self, request: PullClientAppInputsRequest, context: grpc.ServicerContext
|
@@ -109,36 +159,30 @@ class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
|
|
109
159
|
"""Pull Message, Context, and Run."""
|
110
160
|
log(DEBUG, "ClientAppIo.PullClientAppInputs")
|
111
161
|
|
112
|
-
#
|
113
|
-
|
114
|
-
|
115
|
-
grpc.StatusCode.FAILED_PRECONDITION,
|
116
|
-
"No inputs available.",
|
117
|
-
)
|
118
|
-
clientapp_input = cast(ClientAppInputs, self.clientapp_input)
|
162
|
+
# Initialize state and ffs connection
|
163
|
+
state = self.state_factory.state()
|
164
|
+
ffs = self.ffs_factory.ffs()
|
119
165
|
|
120
|
-
#
|
121
|
-
|
166
|
+
# Validate the token
|
167
|
+
run_id = state.get_run_id_by_token(request.token)
|
168
|
+
if run_id is None or not state.verify_token(run_id, request.token):
|
122
169
|
context.abort(
|
123
|
-
grpc.StatusCode.
|
124
|
-
"
|
125
|
-
"Token must be returned before can be returned only once.",
|
170
|
+
grpc.StatusCode.PERMISSION_DENIED,
|
171
|
+
"Invalid token.",
|
126
172
|
)
|
173
|
+
raise RuntimeError("This line should never be reached.")
|
127
174
|
|
128
|
-
#
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
)
|
175
|
+
# Retrieve message, context, run and fab for this run
|
176
|
+
message = state.get_messages(run_ids=[run_id], is_reply=False)[0]
|
177
|
+
context = cast(Context, state.get_context(run_id))
|
178
|
+
run = cast(Run, state.get_run(run_id))
|
179
|
+
fab = Fab(run.fab_hash, ffs.get(run.fab_hash)[0]) # type: ignore
|
134
180
|
|
135
|
-
# Success
|
136
|
-
self.inputs_returned = True
|
137
181
|
return PullClientAppInputsResponse(
|
138
|
-
message=message_to_proto(
|
139
|
-
context=context_to_proto(
|
140
|
-
run=run_to_proto(
|
141
|
-
fab=fab_to_proto(
|
182
|
+
message=message_to_proto(message),
|
183
|
+
context=context_to_proto(context),
|
184
|
+
run=run_to_proto(run),
|
185
|
+
fab=fab_to_proto(fab),
|
142
186
|
)
|
143
187
|
|
144
188
|
def PushClientAppOutputs(
|
@@ -147,36 +191,20 @@ class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
|
|
147
191
|
"""Push Message and Context."""
|
148
192
|
log(DEBUG, "ClientAppIo.PushClientAppOutputs")
|
149
193
|
|
150
|
-
#
|
151
|
-
|
152
|
-
context.abort(
|
153
|
-
grpc.StatusCode.FAILED_PRECONDITION,
|
154
|
-
"No inputs available.",
|
155
|
-
)
|
156
|
-
clientapp_input = cast(ClientAppInputs, self.clientapp_input)
|
194
|
+
# Initialize state connection
|
195
|
+
state = self.state_factory.state()
|
157
196
|
|
158
|
-
#
|
159
|
-
|
197
|
+
# Validate the token
|
198
|
+
run_id = state.get_run_id_by_token(request.token)
|
199
|
+
if run_id is None or not state.verify_token(run_id, request.token):
|
160
200
|
context.abort(
|
161
|
-
grpc.StatusCode.
|
162
|
-
"
|
163
|
-
"Token must be returned before can be returned only once.",
|
201
|
+
grpc.StatusCode.PERMISSION_DENIED,
|
202
|
+
"Invalid token.",
|
164
203
|
)
|
204
|
+
raise RuntimeError("This line should never be reached.")
|
165
205
|
|
166
|
-
#
|
167
|
-
|
168
|
-
context.abort(
|
169
|
-
grpc.StatusCode.FAILED_PRECONDITION,
|
170
|
-
"Inputs haven't been delivered."
|
171
|
-
"Inputs must be delivered before can be returned only once.",
|
172
|
-
)
|
173
|
-
|
174
|
-
# Fail if token isn't matching
|
175
|
-
if request.token != clientapp_input.token:
|
176
|
-
context.abort(
|
177
|
-
grpc.StatusCode.INVALID_ARGUMENT,
|
178
|
-
"Mismatch between ClientApp and SuperNode token",
|
179
|
-
)
|
206
|
+
# Delete the token
|
207
|
+
state.delete_token(run_id)
|
180
208
|
|
181
209
|
# Preconditions met
|
182
210
|
try:
|
@@ -198,33 +226,6 @@ class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
|
|
198
226
|
proto_status = clientappstatus_to_proto(status=status)
|
199
227
|
return PushClientAppOutputsResponse(status=proto_status)
|
200
228
|
|
201
|
-
def set_inputs(
|
202
|
-
self, clientapp_input: ClientAppInputs, token_returned: bool
|
203
|
-
) -> None:
|
204
|
-
"""Set ClientApp inputs.
|
205
|
-
|
206
|
-
Parameters
|
207
|
-
----------
|
208
|
-
clientapp_input : ClientAppInputs
|
209
|
-
The inputs to the ClientApp.
|
210
|
-
token_returned : bool
|
211
|
-
A boolean indicating if the token has been returned.
|
212
|
-
Set to `True` when passing the token to `flwr-clientap`
|
213
|
-
and `False` otherwise.
|
214
|
-
"""
|
215
|
-
if (
|
216
|
-
self.clientapp_input is not None
|
217
|
-
or self.clientapp_output is not None
|
218
|
-
or self.token_returned
|
219
|
-
):
|
220
|
-
raise ValueError(
|
221
|
-
"ClientAppInputs and ClientAppOutputs must not be set before "
|
222
|
-
"calling `set_inputs`."
|
223
|
-
)
|
224
|
-
log(DEBUG, "ClientAppInputs set (token: %s)", clientapp_input.token)
|
225
|
-
self.clientapp_input = clientapp_input
|
226
|
-
self.token_returned = token_returned
|
227
|
-
|
228
229
|
def has_outputs(self) -> bool:
|
229
230
|
"""Check if ClientAppOutputs are available."""
|
230
231
|
return self.clientapp_output is not None
|
@@ -236,9 +237,6 @@ class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
|
|
236
237
|
|
237
238
|
# Set outputs to a local variable and clear state
|
238
239
|
output: ClientAppOutputs = self.clientapp_output
|
239
|
-
self.clientapp_input = None
|
240
240
|
self.clientapp_output = None
|
241
|
-
self.token_returned = False
|
242
|
-
self.inputs_returned = False
|
243
241
|
|
244
242
|
return output
|
@@ -21,9 +21,8 @@ import time
|
|
21
21
|
from collections.abc import Iterator
|
22
22
|
from contextlib import contextmanager
|
23
23
|
from logging import INFO, WARN
|
24
|
-
from os import urandom
|
25
24
|
from pathlib import Path
|
26
|
-
from typing import Callable, Optional, Union
|
25
|
+
from typing import Callable, Optional, Union
|
27
26
|
|
28
27
|
import grpc
|
29
28
|
from cryptography.hazmat.primitives.asymmetric import ec
|
@@ -39,7 +38,6 @@ from flwr.common.constant import (
|
|
39
38
|
CLIENTAPPIO_API_DEFAULT_SERVER_ADDRESS,
|
40
39
|
ISOLATION_MODE_SUBPROCESS,
|
41
40
|
MAX_RETRY_DELAY,
|
42
|
-
RUN_ID_NUM_BYTES,
|
43
41
|
SERVER_OCTET,
|
44
42
|
TRANSPORT_TYPE_GRPC_ADAPTER,
|
45
43
|
TRANSPORT_TYPE_GRPC_RERE,
|
@@ -55,7 +53,7 @@ from flwr.proto.clientappio_pb2_grpc import add_ClientAppIoServicer_to_server
|
|
55
53
|
from flwr.supercore.ffs import Ffs, FfsFactory
|
56
54
|
from flwr.supercore.object_store import ObjectStore, ObjectStoreFactory
|
57
55
|
from flwr.supernode.nodestate import NodeState, NodeStateFactory
|
58
|
-
from flwr.supernode.servicer.clientappio import
|
56
|
+
from flwr.supernode.servicer.clientappio import ClientAppIoServicer
|
59
57
|
|
60
58
|
DEFAULT_FFS_DIR = get_flwr_dir() / "supernode" / "ffs"
|
61
59
|
|
@@ -132,16 +130,20 @@ def start_client_internal(
|
|
132
130
|
if insecure is None:
|
133
131
|
insecure = root_certificates is None
|
134
132
|
|
135
|
-
_clientappio_grpc_server, clientappio_servicer = run_clientappio_api_grpc(
|
136
|
-
address=clientappio_api_address,
|
137
|
-
certificates=None,
|
138
|
-
)
|
139
|
-
|
140
133
|
# Initialize factories
|
141
134
|
state_factory = NodeStateFactory()
|
142
135
|
ffs_factory = FfsFactory(get_flwr_dir(flwr_path) / "supernode" / "ffs") # type: ignore
|
143
136
|
object_store_factory = ObjectStoreFactory()
|
144
137
|
|
138
|
+
# Launch ClientAppIo API server
|
139
|
+
_clientappio_grpc_server, clientappio_servicer = run_clientappio_api_grpc(
|
140
|
+
address=clientappio_api_address,
|
141
|
+
state_factory=state_factory,
|
142
|
+
ffs_factory=ffs_factory,
|
143
|
+
objectstore_factory=object_store_factory,
|
144
|
+
certificates=None,
|
145
|
+
)
|
146
|
+
|
145
147
|
# Initialize NodeState, Ffs, and ObjectStore
|
146
148
|
state = state_factory.state()
|
147
149
|
ffs = ffs_factory.ffs()
|
@@ -183,12 +185,6 @@ def start_client_internal(
|
|
183
185
|
continue
|
184
186
|
|
185
187
|
try:
|
186
|
-
# Retrieve message, context, run and fab for this run
|
187
|
-
message = state.get_messages(run_ids=[run_id], is_reply=False)[0]
|
188
|
-
context = cast(Context, state.get_context(run_id))
|
189
|
-
run = cast(Run, state.get_run(run_id))
|
190
|
-
fab = Fab(run.fab_hash, ffs.get(run.fab_hash)[0]) # type: ignore
|
191
|
-
|
192
188
|
# Two isolation modes:
|
193
189
|
# 1. `subprocess`: SuperNode is starting the ClientApp
|
194
190
|
# process as a subprocess.
|
@@ -196,24 +192,9 @@ def start_client_internal(
|
|
196
192
|
# (via `flwr-clientapp`), for example, in a separate
|
197
193
|
# Docker container.
|
198
194
|
|
199
|
-
# Generate SuperNode token
|
200
|
-
token = int.from_bytes(urandom(RUN_ID_NUM_BYTES), "little")
|
201
|
-
|
202
195
|
# Mode 1: SuperNode starts ClientApp as subprocess
|
203
196
|
start_subprocess = isolation == ISOLATION_MODE_SUBPROCESS
|
204
197
|
|
205
|
-
# Share Message and Context with servicer
|
206
|
-
clientappio_servicer.set_inputs(
|
207
|
-
clientapp_input=ClientAppInputs(
|
208
|
-
message=message,
|
209
|
-
context=context,
|
210
|
-
run=run,
|
211
|
-
fab=fab,
|
212
|
-
token=token,
|
213
|
-
),
|
214
|
-
token_returned=start_subprocess,
|
215
|
-
)
|
216
|
-
|
217
198
|
if start_subprocess:
|
218
199
|
_octet, _colon, _port = clientappio_api_address.rpartition(":")
|
219
200
|
io_address = (
|
@@ -226,11 +207,10 @@ def start_client_internal(
|
|
226
207
|
"flwr-clientapp",
|
227
208
|
"--clientappio-api-address",
|
228
209
|
io_address,
|
229
|
-
"--token",
|
230
|
-
str(token),
|
231
210
|
"--parent-pid",
|
232
211
|
str(os.getpid()),
|
233
212
|
"--insecure",
|
213
|
+
"--run-once",
|
234
214
|
]
|
235
215
|
subprocess.run(command, check=False)
|
236
216
|
else:
|
@@ -250,8 +230,8 @@ def start_client_internal(
|
|
250
230
|
# Delete messages from the state
|
251
231
|
state.delete_messages(
|
252
232
|
message_ids=[
|
253
|
-
|
254
|
-
|
233
|
+
reply_message.metadata.message_id,
|
234
|
+
reply_message.metadata.reply_to_message_id,
|
255
235
|
]
|
256
236
|
)
|
257
237
|
|
@@ -472,10 +452,17 @@ def _make_fleet_connection_retry_invoker(
|
|
472
452
|
|
473
453
|
def run_clientappio_api_grpc(
|
474
454
|
address: str,
|
455
|
+
state_factory: NodeStateFactory,
|
456
|
+
ffs_factory: FfsFactory,
|
457
|
+
objectstore_factory: ObjectStoreFactory,
|
475
458
|
certificates: Optional[tuple[bytes, bytes, bytes]],
|
476
459
|
) -> tuple[grpc.Server, ClientAppIoServicer]:
|
477
460
|
"""Run ClientAppIo API gRPC server."""
|
478
|
-
clientappio_servicer: grpc.Server = ClientAppIoServicer(
|
461
|
+
clientappio_servicer: grpc.Server = ClientAppIoServicer(
|
462
|
+
state_factory=state_factory,
|
463
|
+
ffs_factory=ffs_factory,
|
464
|
+
objectstore_factory=objectstore_factory,
|
465
|
+
)
|
479
466
|
clientappio_add_servicer_to_server_fn = add_ClientAppIoServicer_to_server
|
480
467
|
clientappio_grpc_server = generic_create_grpc_server(
|
481
468
|
servicer_and_add_fn=(
|
{flwr_nightly-1.20.0.dev20250617.dist-info → flwr_nightly-1.20.0.dev20250618.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.20.0.
|
3
|
+
Version: 1.20.0.dev20250618
|
4
4
|
Summary: Flower: A Friendly Federated AI Framework
|
5
5
|
License: Apache-2.0
|
6
6
|
Keywords: Artificial Intelligence,Federated AI,Federated Analytics,Federated Evaluation,Federated Learning,Flower,Machine Learning
|
{flwr_nightly-1.20.0.dev20250617.dist-info → flwr_nightly-1.20.0.dev20250618.dist-info}/RECORD
RENAMED
@@ -164,10 +164,10 @@ flwr/compat/server/__init__.py,sha256=TGVSoOTuf5T5JHUVrK5wuorQF7L6Wvdem8B4uufvMJ
|
|
164
164
|
flwr/compat/server/app.py,sha256=_lIe7Q4KUk-olq9PYBxIsO3UaOn6N92CWgWQ4hRcAZw,6490
|
165
165
|
flwr/compat/simulation/__init__.py,sha256=MApGa-tysDDw34iSdxZ7TWOKtGJM-z3i8fIRJa0qbZ8,750
|
166
166
|
flwr/proto/__init__.py,sha256=S3VbQzVwNC1P-3_9EdrXuwgptO-BVuuAe20Z_OUc1cQ,683
|
167
|
-
flwr/proto/clientappio_pb2.py,sha256=
|
168
|
-
flwr/proto/clientappio_pb2.pyi,sha256=
|
169
|
-
flwr/proto/clientappio_pb2_grpc.py,sha256=
|
170
|
-
flwr/proto/clientappio_pb2_grpc.pyi,sha256=
|
167
|
+
flwr/proto/clientappio_pb2.py,sha256=sI2VLXYaUqEcPHvuh0iCnETAhfHqP2PcvQX6KY_gVMY,4730
|
168
|
+
flwr/proto/clientappio_pb2.pyi,sha256=WFxzJ5jomhuFaQ5RRF1noKuOWAshaCcap4scEAuunVQ,7448
|
169
|
+
flwr/proto/clientappio_pb2_grpc.py,sha256=zVJ0mTgwh5TXvIfBr1hf2l1JT0kg6MCIK9xwwUJbRjc,9634
|
170
|
+
flwr/proto/clientappio_pb2_grpc.pyi,sha256=uvDYLp-Ljf3qk5MI_s05HjHneAi3qo9udVztzfLPXYs,2808
|
171
171
|
flwr/proto/error_pb2.py,sha256=PQVWrfjVPo88ql_KgV9nCxyQNCcV9PVfmcw7sOzTMro,1084
|
172
172
|
flwr/proto/error_pb2.pyi,sha256=ZNH4HhJTU_KfMXlyCeg8FwU-fcUYxTqEmoJPtWtHikc,734
|
173
173
|
flwr/proto/error_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
@@ -348,18 +348,18 @@ flwr/superlink/__init__.py,sha256=GNSuJ4-N6Z8wun2iZNlXqENt5beUyzC0Gi_tN396bbM,70
|
|
348
348
|
flwr/supernode/__init__.py,sha256=KgeCaVvXWrU3rptNR1y0oBp4YtXbAcrnCcJAiOoWkI4,707
|
349
349
|
flwr/supernode/cli/__init__.py,sha256=JuEMr0-s9zv-PEWKuLB9tj1ocNfroSyNJ-oyv7ati9A,887
|
350
350
|
flwr/supernode/cli/flower_supernode.py,sha256=ly2AQhbla2sufDaMsENaEALDEd0a4CS4D0eUrUOkHzY,8778
|
351
|
-
flwr/supernode/cli/flwr_clientapp.py,sha256=
|
351
|
+
flwr/supernode/cli/flwr_clientapp.py,sha256=QeC9TeNq6vrFnYqDPCMym-AieZcp9VrasixkgUFvIAQ,3069
|
352
352
|
flwr/supernode/nodestate/__init__.py,sha256=CyLLObbmmVgfRO88UCM0VMait1dL57mUauUDfuSHsbU,976
|
353
353
|
flwr/supernode/nodestate/in_memory_nodestate.py,sha256=LF3AbaW0bcZHY5yKWwUJSU2RZbMynt-YjFysGqvTOQY,7338
|
354
354
|
flwr/supernode/nodestate/nodestate.py,sha256=kkGFxYnLIwT4-UmlPnf6HvAUpPey2urUNrweGybAIY4,6398
|
355
355
|
flwr/supernode/nodestate/nodestate_factory.py,sha256=UYTDCcwK_baHUmkzkJDxL0UEqvtTfOMlQRrROMCd0Xo,1430
|
356
356
|
flwr/supernode/runtime/__init__.py,sha256=JQdqd2EMTn-ORMeTvewYYh52ls0YKP68jrps1qioxu4,718
|
357
|
-
flwr/supernode/runtime/run_clientapp.py,sha256=
|
357
|
+
flwr/supernode/runtime/run_clientapp.py,sha256=k6R5PKRTEJQ0gfCOhNb6K8HVMyIJyhm_TdtJE5Jy0hA,8027
|
358
358
|
flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca8gxdEo,717
|
359
359
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=vJyOjO2FXZ2URbnthmdsgs6948wbYfdq1L1V8Um-Lr8,895
|
360
|
-
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=
|
361
|
-
flwr/supernode/start_client_internal.py,sha256=
|
362
|
-
flwr_nightly-1.20.0.
|
363
|
-
flwr_nightly-1.20.0.
|
364
|
-
flwr_nightly-1.20.0.
|
365
|
-
flwr_nightly-1.20.0.
|
360
|
+
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=QGJhRwgGYnxQjLJk8wA6-25AIw3NH0QRjBfgvmHErRU,8302
|
361
|
+
flwr/supernode/start_client_internal.py,sha256=gpIv0vIfMVJzNt8qOf6PGHeqRWHMb_MkpArvYvj_45g,17831
|
362
|
+
flwr_nightly-1.20.0.dev20250618.dist-info/METADATA,sha256=PTDjvTipZ8rFu-CkqCn3-W1UPs6ClM10p0wtQ1Hva4c,15910
|
363
|
+
flwr_nightly-1.20.0.dev20250618.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
364
|
+
flwr_nightly-1.20.0.dev20250618.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
|
365
|
+
flwr_nightly-1.20.0.dev20250618.dist-info/RECORD,,
|
{flwr_nightly-1.20.0.dev20250617.dist-info → flwr_nightly-1.20.0.dev20250618.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|