flwr-nightly 1.10.0.dev20240612__py3-none-any.whl → 1.10.0.dev20240619__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.
Potentially problematic release.
This version of flwr-nightly might be problematic. Click here for more details.
- flwr/cli/build.py +3 -1
- flwr/cli/config_utils.py +53 -3
- flwr/cli/install.py +35 -20
- flwr/cli/run/run.py +39 -2
- flwr/client/__init__.py +1 -1
- flwr/client/app.py +22 -10
- flwr/client/grpc_adapter_client/__init__.py +15 -0
- flwr/client/grpc_adapter_client/connection.py +94 -0
- flwr/client/grpc_client/connection.py +5 -1
- flwr/client/grpc_rere_client/connection.py +8 -1
- flwr/client/grpc_rere_client/grpc_adapter.py +133 -0
- flwr/client/mod/__init__.py +3 -3
- flwr/client/rest_client/connection.py +9 -1
- flwr/client/supernode/app.py +140 -40
- flwr/common/__init__.py +12 -12
- flwr/common/config.py +71 -0
- flwr/common/constant.py +15 -0
- flwr/common/object_ref.py +39 -5
- flwr/common/record/__init__.py +1 -1
- flwr/common/telemetry.py +4 -0
- flwr/common/typing.py +9 -0
- flwr/proto/exec_pb2.py +34 -0
- flwr/proto/exec_pb2.pyi +55 -0
- flwr/proto/exec_pb2_grpc.py +101 -0
- flwr/proto/exec_pb2_grpc.pyi +41 -0
- flwr/proto/fab_pb2.py +30 -0
- flwr/proto/fab_pb2.pyi +56 -0
- flwr/proto/fab_pb2_grpc.py +4 -0
- flwr/proto/fab_pb2_grpc.pyi +4 -0
- flwr/server/__init__.py +2 -2
- flwr/server/app.py +62 -25
- flwr/server/run_serverapp.py +4 -2
- flwr/server/strategy/__init__.py +2 -2
- flwr/server/superlink/fleet/grpc_adapter/__init__.py +15 -0
- flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +131 -0
- flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +4 -0
- flwr/server/superlink/fleet/message_handler/message_handler.py +3 -3
- flwr/server/superlink/fleet/vce/vce_api.py +3 -1
- flwr/server/superlink/state/in_memory_state.py +8 -5
- flwr/server/superlink/state/sqlite_state.py +6 -3
- flwr/server/superlink/state/state.py +5 -4
- flwr/simulation/__init__.py +4 -1
- flwr/simulation/run_simulation.py +22 -0
- flwr/superexec/__init__.py +21 -0
- flwr/superexec/app.py +178 -0
- flwr/superexec/exec_grpc.py +51 -0
- flwr/superexec/exec_servicer.py +65 -0
- flwr/superexec/executor.py +54 -0
- {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240619.dist-info}/METADATA +1 -1
- {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240619.dist-info}/RECORD +53 -34
- {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240619.dist-info}/entry_points.txt +1 -0
- {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240619.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240619.dist-info}/WHEEL +0 -0
flwr/proto/exec_pb2.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: flwr/proto/exec.proto
|
|
4
|
+
# Protobuf Python Version: 4.25.0
|
|
5
|
+
"""Generated protocol buffer code."""
|
|
6
|
+
from google.protobuf import descriptor as _descriptor
|
|
7
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
8
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
9
|
+
from google.protobuf.internal import builder as _builder
|
|
10
|
+
# @@protoc_insertion_point(imports)
|
|
11
|
+
|
|
12
|
+
_sym_db = _symbol_database.Default()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\"#\n\x0fStartRunRequest\x12\x10\n\x08\x66\x61\x62_file\x18\x01 \x01(\x0c\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"#\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"(\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')
|
|
18
|
+
|
|
19
|
+
_globals = globals()
|
|
20
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
21
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.exec_pb2', _globals)
|
|
22
|
+
if _descriptor._USE_C_DESCRIPTORS == False:
|
|
23
|
+
DESCRIPTOR._options = None
|
|
24
|
+
_globals['_STARTRUNREQUEST']._serialized_start=37
|
|
25
|
+
_globals['_STARTRUNREQUEST']._serialized_end=72
|
|
26
|
+
_globals['_STARTRUNRESPONSE']._serialized_start=74
|
|
27
|
+
_globals['_STARTRUNRESPONSE']._serialized_end=108
|
|
28
|
+
_globals['_STREAMLOGSREQUEST']._serialized_start=110
|
|
29
|
+
_globals['_STREAMLOGSREQUEST']._serialized_end=145
|
|
30
|
+
_globals['_STREAMLOGSRESPONSE']._serialized_start=147
|
|
31
|
+
_globals['_STREAMLOGSRESPONSE']._serialized_end=187
|
|
32
|
+
_globals['_EXEC']._serialized_start=190
|
|
33
|
+
_globals['_EXEC']._serialized_end=350
|
|
34
|
+
# @@protoc_insertion_point(module_scope)
|
flwr/proto/exec_pb2.pyi
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
@generated by mypy-protobuf. Do not edit manually!
|
|
3
|
+
isort:skip_file
|
|
4
|
+
"""
|
|
5
|
+
import builtins
|
|
6
|
+
import google.protobuf.descriptor
|
|
7
|
+
import google.protobuf.message
|
|
8
|
+
import typing
|
|
9
|
+
import typing_extensions
|
|
10
|
+
|
|
11
|
+
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
|
12
|
+
|
|
13
|
+
class StartRunRequest(google.protobuf.message.Message):
|
|
14
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
15
|
+
FAB_FILE_FIELD_NUMBER: builtins.int
|
|
16
|
+
fab_file: builtins.bytes
|
|
17
|
+
def __init__(self,
|
|
18
|
+
*,
|
|
19
|
+
fab_file: builtins.bytes = ...,
|
|
20
|
+
) -> None: ...
|
|
21
|
+
def ClearField(self, field_name: typing_extensions.Literal["fab_file",b"fab_file"]) -> None: ...
|
|
22
|
+
global___StartRunRequest = StartRunRequest
|
|
23
|
+
|
|
24
|
+
class StartRunResponse(google.protobuf.message.Message):
|
|
25
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
26
|
+
RUN_ID_FIELD_NUMBER: builtins.int
|
|
27
|
+
run_id: builtins.int
|
|
28
|
+
def __init__(self,
|
|
29
|
+
*,
|
|
30
|
+
run_id: builtins.int = ...,
|
|
31
|
+
) -> None: ...
|
|
32
|
+
def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ...
|
|
33
|
+
global___StartRunResponse = StartRunResponse
|
|
34
|
+
|
|
35
|
+
class StreamLogsRequest(google.protobuf.message.Message):
|
|
36
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
37
|
+
RUN_ID_FIELD_NUMBER: builtins.int
|
|
38
|
+
run_id: builtins.int
|
|
39
|
+
def __init__(self,
|
|
40
|
+
*,
|
|
41
|
+
run_id: builtins.int = ...,
|
|
42
|
+
) -> None: ...
|
|
43
|
+
def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ...
|
|
44
|
+
global___StreamLogsRequest = StreamLogsRequest
|
|
45
|
+
|
|
46
|
+
class StreamLogsResponse(google.protobuf.message.Message):
|
|
47
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
48
|
+
LOG_OUTPUT_FIELD_NUMBER: builtins.int
|
|
49
|
+
log_output: typing.Text
|
|
50
|
+
def __init__(self,
|
|
51
|
+
*,
|
|
52
|
+
log_output: typing.Text = ...,
|
|
53
|
+
) -> None: ...
|
|
54
|
+
def ClearField(self, field_name: typing_extensions.Literal["log_output",b"log_output"]) -> None: ...
|
|
55
|
+
global___StreamLogsResponse = StreamLogsResponse
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
|
2
|
+
"""Client and server classes corresponding to protobuf-defined services."""
|
|
3
|
+
import grpc
|
|
4
|
+
|
|
5
|
+
from flwr.proto import exec_pb2 as flwr_dot_proto_dot_exec__pb2
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ExecStub(object):
|
|
9
|
+
"""Missing associated documentation comment in .proto file."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, channel):
|
|
12
|
+
"""Constructor.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
channel: A grpc.Channel.
|
|
16
|
+
"""
|
|
17
|
+
self.StartRun = channel.unary_unary(
|
|
18
|
+
'/flwr.proto.Exec/StartRun',
|
|
19
|
+
request_serializer=flwr_dot_proto_dot_exec__pb2.StartRunRequest.SerializeToString,
|
|
20
|
+
response_deserializer=flwr_dot_proto_dot_exec__pb2.StartRunResponse.FromString,
|
|
21
|
+
)
|
|
22
|
+
self.StreamLogs = channel.unary_stream(
|
|
23
|
+
'/flwr.proto.Exec/StreamLogs',
|
|
24
|
+
request_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.SerializeToString,
|
|
25
|
+
response_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ExecServicer(object):
|
|
30
|
+
"""Missing associated documentation comment in .proto file."""
|
|
31
|
+
|
|
32
|
+
def StartRun(self, request, context):
|
|
33
|
+
"""Start run upon request
|
|
34
|
+
"""
|
|
35
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
36
|
+
context.set_details('Method not implemented!')
|
|
37
|
+
raise NotImplementedError('Method not implemented!')
|
|
38
|
+
|
|
39
|
+
def StreamLogs(self, request, context):
|
|
40
|
+
"""Start log stream upon request
|
|
41
|
+
"""
|
|
42
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
43
|
+
context.set_details('Method not implemented!')
|
|
44
|
+
raise NotImplementedError('Method not implemented!')
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def add_ExecServicer_to_server(servicer, server):
|
|
48
|
+
rpc_method_handlers = {
|
|
49
|
+
'StartRun': grpc.unary_unary_rpc_method_handler(
|
|
50
|
+
servicer.StartRun,
|
|
51
|
+
request_deserializer=flwr_dot_proto_dot_exec__pb2.StartRunRequest.FromString,
|
|
52
|
+
response_serializer=flwr_dot_proto_dot_exec__pb2.StartRunResponse.SerializeToString,
|
|
53
|
+
),
|
|
54
|
+
'StreamLogs': grpc.unary_stream_rpc_method_handler(
|
|
55
|
+
servicer.StreamLogs,
|
|
56
|
+
request_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.FromString,
|
|
57
|
+
response_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.SerializeToString,
|
|
58
|
+
),
|
|
59
|
+
}
|
|
60
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
|
61
|
+
'flwr.proto.Exec', rpc_method_handlers)
|
|
62
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# This class is part of an EXPERIMENTAL API.
|
|
66
|
+
class Exec(object):
|
|
67
|
+
"""Missing associated documentation comment in .proto file."""
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def StartRun(request,
|
|
71
|
+
target,
|
|
72
|
+
options=(),
|
|
73
|
+
channel_credentials=None,
|
|
74
|
+
call_credentials=None,
|
|
75
|
+
insecure=False,
|
|
76
|
+
compression=None,
|
|
77
|
+
wait_for_ready=None,
|
|
78
|
+
timeout=None,
|
|
79
|
+
metadata=None):
|
|
80
|
+
return grpc.experimental.unary_unary(request, target, '/flwr.proto.Exec/StartRun',
|
|
81
|
+
flwr_dot_proto_dot_exec__pb2.StartRunRequest.SerializeToString,
|
|
82
|
+
flwr_dot_proto_dot_exec__pb2.StartRunResponse.FromString,
|
|
83
|
+
options, channel_credentials,
|
|
84
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
85
|
+
|
|
86
|
+
@staticmethod
|
|
87
|
+
def StreamLogs(request,
|
|
88
|
+
target,
|
|
89
|
+
options=(),
|
|
90
|
+
channel_credentials=None,
|
|
91
|
+
call_credentials=None,
|
|
92
|
+
insecure=False,
|
|
93
|
+
compression=None,
|
|
94
|
+
wait_for_ready=None,
|
|
95
|
+
timeout=None,
|
|
96
|
+
metadata=None):
|
|
97
|
+
return grpc.experimental.unary_stream(request, target, '/flwr.proto.Exec/StreamLogs',
|
|
98
|
+
flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.SerializeToString,
|
|
99
|
+
flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString,
|
|
100
|
+
options, channel_credentials,
|
|
101
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
@generated by mypy-protobuf. Do not edit manually!
|
|
3
|
+
isort:skip_file
|
|
4
|
+
"""
|
|
5
|
+
import abc
|
|
6
|
+
import flwr.proto.exec_pb2
|
|
7
|
+
import grpc
|
|
8
|
+
import typing
|
|
9
|
+
|
|
10
|
+
class ExecStub:
|
|
11
|
+
def __init__(self, channel: grpc.Channel) -> None: ...
|
|
12
|
+
StartRun: grpc.UnaryUnaryMultiCallable[
|
|
13
|
+
flwr.proto.exec_pb2.StartRunRequest,
|
|
14
|
+
flwr.proto.exec_pb2.StartRunResponse]
|
|
15
|
+
"""Start run upon request"""
|
|
16
|
+
|
|
17
|
+
StreamLogs: grpc.UnaryStreamMultiCallable[
|
|
18
|
+
flwr.proto.exec_pb2.StreamLogsRequest,
|
|
19
|
+
flwr.proto.exec_pb2.StreamLogsResponse]
|
|
20
|
+
"""Start log stream upon request"""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ExecServicer(metaclass=abc.ABCMeta):
|
|
24
|
+
@abc.abstractmethod
|
|
25
|
+
def StartRun(self,
|
|
26
|
+
request: flwr.proto.exec_pb2.StartRunRequest,
|
|
27
|
+
context: grpc.ServicerContext,
|
|
28
|
+
) -> flwr.proto.exec_pb2.StartRunResponse:
|
|
29
|
+
"""Start run upon request"""
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
@abc.abstractmethod
|
|
33
|
+
def StreamLogs(self,
|
|
34
|
+
request: flwr.proto.exec_pb2.StreamLogsRequest,
|
|
35
|
+
context: grpc.ServicerContext,
|
|
36
|
+
) -> typing.Iterator[flwr.proto.exec_pb2.StreamLogsResponse]:
|
|
37
|
+
"""Start log stream upon request"""
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def add_ExecServicer_to_server(servicer: ExecServicer, server: grpc.Server) -> None: ...
|
flwr/proto/fab_pb2.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: flwr/proto/fab.proto
|
|
4
|
+
# Protobuf Python Version: 4.25.0
|
|
5
|
+
"""Generated protocol buffer code."""
|
|
6
|
+
from google.protobuf import descriptor as _descriptor
|
|
7
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
8
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
9
|
+
from google.protobuf.internal import builder as _builder
|
|
10
|
+
# @@protoc_insertion_point(imports)
|
|
11
|
+
|
|
12
|
+
_sym_db = _symbol_database.Default()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\"$\n\x03\x46\x61\x62\x12\x0c\n\x04hash\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\x0c\"\x1d\n\rGetFabRequest\x12\x0c\n\x04hash\x18\x01 \x01(\t\".\n\x0eGetFabResponse\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fabb\x06proto3')
|
|
18
|
+
|
|
19
|
+
_globals = globals()
|
|
20
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
21
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.fab_pb2', _globals)
|
|
22
|
+
if _descriptor._USE_C_DESCRIPTORS == False:
|
|
23
|
+
DESCRIPTOR._options = None
|
|
24
|
+
_globals['_FAB']._serialized_start=36
|
|
25
|
+
_globals['_FAB']._serialized_end=72
|
|
26
|
+
_globals['_GETFABREQUEST']._serialized_start=74
|
|
27
|
+
_globals['_GETFABREQUEST']._serialized_end=103
|
|
28
|
+
_globals['_GETFABRESPONSE']._serialized_start=105
|
|
29
|
+
_globals['_GETFABRESPONSE']._serialized_end=151
|
|
30
|
+
# @@protoc_insertion_point(module_scope)
|
flwr/proto/fab_pb2.pyi
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
@generated by mypy-protobuf. Do not edit manually!
|
|
3
|
+
isort:skip_file
|
|
4
|
+
"""
|
|
5
|
+
import builtins
|
|
6
|
+
import google.protobuf.descriptor
|
|
7
|
+
import google.protobuf.message
|
|
8
|
+
import typing
|
|
9
|
+
import typing_extensions
|
|
10
|
+
|
|
11
|
+
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
|
12
|
+
|
|
13
|
+
class Fab(google.protobuf.message.Message):
|
|
14
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
15
|
+
HASH_FIELD_NUMBER: builtins.int
|
|
16
|
+
CONTENT_FIELD_NUMBER: builtins.int
|
|
17
|
+
hash: typing.Text
|
|
18
|
+
"""This field is the hash of the data field. It is used to identify the data.
|
|
19
|
+
The hash is calculated using the SHA-256 algorithm and is represented as a
|
|
20
|
+
hex string (sha256hex).
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
content: builtins.bytes
|
|
24
|
+
"""This field contains the fab file contents a one bytes blob."""
|
|
25
|
+
|
|
26
|
+
def __init__(self,
|
|
27
|
+
*,
|
|
28
|
+
hash: typing.Text = ...,
|
|
29
|
+
content: builtins.bytes = ...,
|
|
30
|
+
) -> None: ...
|
|
31
|
+
def ClearField(self, field_name: typing_extensions.Literal["content",b"content","hash",b"hash"]) -> None: ...
|
|
32
|
+
global___Fab = Fab
|
|
33
|
+
|
|
34
|
+
class GetFabRequest(google.protobuf.message.Message):
|
|
35
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
36
|
+
HASH_FIELD_NUMBER: builtins.int
|
|
37
|
+
hash: typing.Text
|
|
38
|
+
def __init__(self,
|
|
39
|
+
*,
|
|
40
|
+
hash: typing.Text = ...,
|
|
41
|
+
) -> None: ...
|
|
42
|
+
def ClearField(self, field_name: typing_extensions.Literal["hash",b"hash"]) -> None: ...
|
|
43
|
+
global___GetFabRequest = GetFabRequest
|
|
44
|
+
|
|
45
|
+
class GetFabResponse(google.protobuf.message.Message):
|
|
46
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
47
|
+
FAB_FIELD_NUMBER: builtins.int
|
|
48
|
+
@property
|
|
49
|
+
def fab(self) -> global___Fab: ...
|
|
50
|
+
def __init__(self,
|
|
51
|
+
*,
|
|
52
|
+
fab: typing.Optional[global___Fab] = ...,
|
|
53
|
+
) -> None: ...
|
|
54
|
+
def HasField(self, field_name: typing_extensions.Literal["fab",b"fab"]) -> builtins.bool: ...
|
|
55
|
+
def ClearField(self, field_name: typing_extensions.Literal["fab",b"fab"]) -> None: ...
|
|
56
|
+
global___GetFabResponse = GetFabResponse
|
flwr/server/__init__.py
CHANGED
|
@@ -34,12 +34,12 @@ __all__ = [
|
|
|
34
34
|
"Driver",
|
|
35
35
|
"History",
|
|
36
36
|
"LegacyContext",
|
|
37
|
-
"run_server_app",
|
|
38
|
-
"run_superlink",
|
|
39
37
|
"Server",
|
|
40
38
|
"ServerApp",
|
|
41
39
|
"ServerConfig",
|
|
42
40
|
"SimpleClientManager",
|
|
41
|
+
"run_server_app",
|
|
42
|
+
"run_superlink",
|
|
43
43
|
"start_server",
|
|
44
44
|
"strategy",
|
|
45
45
|
"workflow",
|
flwr/server/app.py
CHANGED
|
@@ -36,6 +36,7 @@ from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, event
|
|
|
36
36
|
from flwr.common.address import parse_address
|
|
37
37
|
from flwr.common.constant import (
|
|
38
38
|
MISSING_EXTRA_REST,
|
|
39
|
+
TRANSPORT_TYPE_GRPC_ADAPTER,
|
|
39
40
|
TRANSPORT_TYPE_GRPC_RERE,
|
|
40
41
|
TRANSPORT_TYPE_REST,
|
|
41
42
|
)
|
|
@@ -48,6 +49,7 @@ from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
|
|
|
48
49
|
from flwr.proto.fleet_pb2_grpc import ( # pylint: disable=E0611
|
|
49
50
|
add_FleetServicer_to_server,
|
|
50
51
|
)
|
|
52
|
+
from flwr.proto.grpcadapter_pb2_grpc import add_GrpcAdapterServicer_to_server
|
|
51
53
|
|
|
52
54
|
from .client_manager import ClientManager
|
|
53
55
|
from .history import History
|
|
@@ -55,6 +57,7 @@ from .server import Server, init_defaults, run_fl
|
|
|
55
57
|
from .server_config import ServerConfig
|
|
56
58
|
from .strategy import Strategy
|
|
57
59
|
from .superlink.driver.driver_grpc import run_driver_api_grpc
|
|
60
|
+
from .superlink.fleet.grpc_adapter.grpc_adapter_servicer import GrpcAdapterServicer
|
|
58
61
|
from .superlink.fleet.grpc_bidi.grpc_server import (
|
|
59
62
|
generic_create_grpc_server,
|
|
60
63
|
start_grpc_server,
|
|
@@ -200,15 +203,7 @@ def run_superlink() -> None:
|
|
|
200
203
|
args = _parse_args_run_superlink().parse_args()
|
|
201
204
|
|
|
202
205
|
# Parse IP address
|
|
203
|
-
|
|
204
|
-
if not parsed_driver_address:
|
|
205
|
-
sys.exit(f"Driver IP address ({args.driver_api_address}) cannot be parsed.")
|
|
206
|
-
driver_host, driver_port, driver_is_v6 = parsed_driver_address
|
|
207
|
-
driver_address = (
|
|
208
|
-
f"[{driver_host}]:{driver_port}"
|
|
209
|
-
if driver_is_v6
|
|
210
|
-
else f"{driver_host}:{driver_port}"
|
|
211
|
-
)
|
|
206
|
+
driver_address, _, _ = _format_address(args.driver_api_address)
|
|
212
207
|
|
|
213
208
|
# Obtain certificates
|
|
214
209
|
certificates = _try_obtain_certificates(args)
|
|
@@ -226,18 +221,15 @@ def run_superlink() -> None:
|
|
|
226
221
|
grpc_servers = [driver_server]
|
|
227
222
|
bckg_threads = []
|
|
228
223
|
if not args.fleet_api_address:
|
|
229
|
-
args.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
fleet_address = (
|
|
239
|
-
f"[{fleet_host}]:{fleet_port}" if fleet_is_v6 else f"{fleet_host}:{fleet_port}"
|
|
240
|
-
)
|
|
224
|
+
if args.fleet_api_type in [
|
|
225
|
+
TRANSPORT_TYPE_GRPC_RERE,
|
|
226
|
+
TRANSPORT_TYPE_GRPC_ADAPTER,
|
|
227
|
+
]:
|
|
228
|
+
args.fleet_api_address = ADDRESS_FLEET_API_GRPC_RERE
|
|
229
|
+
elif args.fleet_api_type == TRANSPORT_TYPE_REST:
|
|
230
|
+
args.fleet_api_address = ADDRESS_FLEET_API_REST
|
|
231
|
+
|
|
232
|
+
fleet_address, host, port = _format_address(args.fleet_api_address)
|
|
241
233
|
|
|
242
234
|
num_workers = args.fleet_api_num_workers
|
|
243
235
|
if num_workers != 1:
|
|
@@ -267,8 +259,8 @@ def run_superlink() -> None:
|
|
|
267
259
|
fleet_thread = threading.Thread(
|
|
268
260
|
target=_run_fleet_api_rest,
|
|
269
261
|
args=(
|
|
270
|
-
|
|
271
|
-
|
|
262
|
+
host,
|
|
263
|
+
port,
|
|
272
264
|
ssl_keyfile,
|
|
273
265
|
ssl_certfile,
|
|
274
266
|
state_factory,
|
|
@@ -306,6 +298,13 @@ def run_superlink() -> None:
|
|
|
306
298
|
interceptors=interceptors,
|
|
307
299
|
)
|
|
308
300
|
grpc_servers.append(fleet_server)
|
|
301
|
+
elif args.fleet_api_type == TRANSPORT_TYPE_GRPC_ADAPTER:
|
|
302
|
+
fleet_server = _run_fleet_api_grpc_adapter(
|
|
303
|
+
address=fleet_address,
|
|
304
|
+
state_factory=state_factory,
|
|
305
|
+
certificates=certificates,
|
|
306
|
+
)
|
|
307
|
+
grpc_servers.append(fleet_server)
|
|
309
308
|
else:
|
|
310
309
|
raise ValueError(f"Unknown fleet_api_type: {args.fleet_api_type}")
|
|
311
310
|
|
|
@@ -325,6 +324,16 @@ def run_superlink() -> None:
|
|
|
325
324
|
driver_server.wait_for_termination(timeout=1)
|
|
326
325
|
|
|
327
326
|
|
|
327
|
+
def _format_address(address: str) -> Tuple[str, str, int]:
|
|
328
|
+
parsed_address = parse_address(address)
|
|
329
|
+
if not parsed_address:
|
|
330
|
+
sys.exit(
|
|
331
|
+
f"Address ({address}) cannot be parsed (expected: URL or IPv4 or IPv6)."
|
|
332
|
+
)
|
|
333
|
+
host, port, is_v6 = parsed_address
|
|
334
|
+
return (f"[{host}]:{port}" if is_v6 else f"{host}:{port}", host, port)
|
|
335
|
+
|
|
336
|
+
|
|
328
337
|
def _try_setup_client_authentication(
|
|
329
338
|
args: argparse.Namespace,
|
|
330
339
|
certificates: Optional[Tuple[bytes, bytes, bytes]],
|
|
@@ -422,7 +431,7 @@ def _try_obtain_certificates(
|
|
|
422
431
|
log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.")
|
|
423
432
|
return None
|
|
424
433
|
# Check if certificates are provided
|
|
425
|
-
if args.fleet_api_type
|
|
434
|
+
if args.fleet_api_type in [TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_GRPC_ADAPTER]:
|
|
426
435
|
if args.ssl_certfile and args.ssl_keyfile and args.ssl_ca_certfile:
|
|
427
436
|
if not isfile(args.ssl_ca_certfile):
|
|
428
437
|
sys.exit("Path argument `--ssl-ca-certfile` does not point to a file.")
|
|
@@ -494,6 +503,30 @@ def _run_fleet_api_grpc_rere(
|
|
|
494
503
|
return fleet_grpc_server
|
|
495
504
|
|
|
496
505
|
|
|
506
|
+
def _run_fleet_api_grpc_adapter(
|
|
507
|
+
address: str,
|
|
508
|
+
state_factory: StateFactory,
|
|
509
|
+
certificates: Optional[Tuple[bytes, bytes, bytes]],
|
|
510
|
+
) -> grpc.Server:
|
|
511
|
+
"""Run Fleet API (GrpcAdapter)."""
|
|
512
|
+
# Create Fleet API gRPC server
|
|
513
|
+
fleet_servicer = GrpcAdapterServicer(
|
|
514
|
+
state_factory=state_factory,
|
|
515
|
+
)
|
|
516
|
+
fleet_add_servicer_to_server_fn = add_GrpcAdapterServicer_to_server
|
|
517
|
+
fleet_grpc_server = generic_create_grpc_server(
|
|
518
|
+
servicer_and_add_fn=(fleet_servicer, fleet_add_servicer_to_server_fn),
|
|
519
|
+
server_address=address,
|
|
520
|
+
max_message_length=GRPC_MAX_MESSAGE_LENGTH,
|
|
521
|
+
certificates=certificates,
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
log(INFO, "Flower ECE: Starting Fleet API (GrpcAdapter) on %s", address)
|
|
525
|
+
fleet_grpc_server.start()
|
|
526
|
+
|
|
527
|
+
return fleet_grpc_server
|
|
528
|
+
|
|
529
|
+
|
|
497
530
|
# pylint: disable=import-outside-toplevel,too-many-arguments
|
|
498
531
|
def _run_fleet_api_rest(
|
|
499
532
|
host: str,
|
|
@@ -609,7 +642,11 @@ def _add_args_fleet_api(parser: argparse.ArgumentParser) -> None:
|
|
|
609
642
|
"--fleet-api-type",
|
|
610
643
|
default=TRANSPORT_TYPE_GRPC_RERE,
|
|
611
644
|
type=str,
|
|
612
|
-
choices=[
|
|
645
|
+
choices=[
|
|
646
|
+
TRANSPORT_TYPE_GRPC_RERE,
|
|
647
|
+
TRANSPORT_TYPE_GRPC_ADAPTER,
|
|
648
|
+
TRANSPORT_TYPE_REST,
|
|
649
|
+
],
|
|
613
650
|
help="Start a gRPC-rere or REST (experimental) Fleet API server.",
|
|
614
651
|
)
|
|
615
652
|
parser.add_argument(
|
flwr/server/run_serverapp.py
CHANGED
|
@@ -45,12 +45,14 @@ def run(
|
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
if server_app_dir is not None:
|
|
48
|
-
sys.path.insert(0, server_app_dir)
|
|
48
|
+
sys.path.insert(0, str(Path(server_app_dir).absolute()))
|
|
49
49
|
|
|
50
50
|
# Load ServerApp if needed
|
|
51
51
|
def _load() -> ServerApp:
|
|
52
52
|
if server_app_attr:
|
|
53
|
-
server_app: ServerApp = load_app(
|
|
53
|
+
server_app: ServerApp = load_app(
|
|
54
|
+
server_app_attr, LoadServerAppError, server_app_dir
|
|
55
|
+
)
|
|
54
56
|
|
|
55
57
|
if not isinstance(server_app, ServerApp):
|
|
56
58
|
raise LoadServerAppError(
|
flwr/server/strategy/__init__.py
CHANGED
|
@@ -53,9 +53,10 @@ __all__ = [
|
|
|
53
53
|
"DPFedAvgAdaptive",
|
|
54
54
|
"DPFedAvgFixed",
|
|
55
55
|
"DifferentialPrivacyClientSideAdaptiveClipping",
|
|
56
|
-
"DifferentialPrivacyServerSideAdaptiveClipping",
|
|
57
56
|
"DifferentialPrivacyClientSideFixedClipping",
|
|
57
|
+
"DifferentialPrivacyServerSideAdaptiveClipping",
|
|
58
58
|
"DifferentialPrivacyServerSideFixedClipping",
|
|
59
|
+
"FaultTolerantFedAvg",
|
|
59
60
|
"FedAdagrad",
|
|
60
61
|
"FedAdam",
|
|
61
62
|
"FedAvg",
|
|
@@ -69,7 +70,6 @@ __all__ = [
|
|
|
69
70
|
"FedXgbCyclic",
|
|
70
71
|
"FedXgbNnAvg",
|
|
71
72
|
"FedYogi",
|
|
72
|
-
"FaultTolerantFedAvg",
|
|
73
73
|
"Krum",
|
|
74
74
|
"QFedAvg",
|
|
75
75
|
"Strategy",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright 2024 Flower Labs GmbH. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
"""Server-side part of the GrpcAdapter transport layer."""
|