flwr-nightly 1.14.0.dev20241211__py3-none-any.whl → 1.14.0.dev20241212__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/new/new.py +1 -1
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -2
- flwr/client/mod/localdp_mod.py +1 -1
- flwr/common/object_ref.py +57 -54
- flwr/common/retry_invoker.py +75 -0
- flwr/common/typing.py +4 -0
- flwr/proto/fab_pb2.py +4 -4
- flwr/proto/fab_pb2.pyi +4 -1
- flwr/server/compat/app_utils.py +7 -1
- flwr/server/driver/grpc_driver.py +4 -61
- flwr/server/serverapp/app.py +8 -2
- flwr/server/superlink/driver/serverappio_servicer.py +50 -6
- flwr/server/superlink/utils.py +65 -0
- {flwr_nightly-1.14.0.dev20241211.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/METADATA +1 -1
- {flwr_nightly-1.14.0.dev20241211.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/RECORD +18 -17
- {flwr_nightly-1.14.0.dev20241211.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.14.0.dev20241211.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.14.0.dev20241211.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/entry_points.txt +0 -0
flwr/cli/new/new.py
CHANGED
|
@@ -81,7 +81,7 @@ def render_template(template: str, data: dict[str, str]) -> str:
|
|
|
81
81
|
def create_file(file_path: Path, content: str) -> None:
|
|
82
82
|
"""Create file including all nessecary directories and write content into file."""
|
|
83
83
|
file_path.parent.mkdir(exist_ok=True)
|
|
84
|
-
file_path.write_text(content)
|
|
84
|
+
file_path.write_text(content, encoding="utf-8")
|
|
85
85
|
|
|
86
86
|
|
|
87
87
|
def render_and_create(file_path: Path, template: str, context: dict[str, str]) -> None:
|
flwr/client/mod/localdp_mod.py
CHANGED
|
@@ -136,7 +136,7 @@ class LocalDpMod:
|
|
|
136
136
|
fit_res.parameters = ndarrays_to_parameters(client_to_server_params)
|
|
137
137
|
|
|
138
138
|
# Add noise to model params
|
|
139
|
-
add_localdp_gaussian_noise_to_params(
|
|
139
|
+
fit_res.parameters = add_localdp_gaussian_noise_to_params(
|
|
140
140
|
fit_res.parameters, self.sensitivity, self.epsilon, self.delta
|
|
141
141
|
)
|
|
142
142
|
|
flwr/common/object_ref.py
CHANGED
|
@@ -21,6 +21,7 @@ import sys
|
|
|
21
21
|
from importlib.util import find_spec
|
|
22
22
|
from logging import WARN
|
|
23
23
|
from pathlib import Path
|
|
24
|
+
from threading import Lock
|
|
24
25
|
from typing import Any, Optional, Union
|
|
25
26
|
|
|
26
27
|
from .logger import log
|
|
@@ -34,6 +35,7 @@ attribute.
|
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
_current_sys_path: Optional[str] = None
|
|
38
|
+
_import_lock = Lock()
|
|
37
39
|
|
|
38
40
|
|
|
39
41
|
def validate(
|
|
@@ -146,60 +148,61 @@ def load_app( # pylint: disable= too-many-branches
|
|
|
146
148
|
- This function will modify `sys.path` by inserting the provided `project_dir`
|
|
147
149
|
and removing the previously inserted `project_dir`.
|
|
148
150
|
"""
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
project_dir
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
151
|
+
with _import_lock:
|
|
152
|
+
valid, error_msg = validate(module_attribute_str, check_module=False)
|
|
153
|
+
if not valid and error_msg:
|
|
154
|
+
raise error_type(error_msg) from None
|
|
155
|
+
|
|
156
|
+
module_str, _, attributes_str = module_attribute_str.partition(":")
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
# Initialize project path
|
|
160
|
+
if project_dir is None:
|
|
161
|
+
project_dir = Path.cwd()
|
|
162
|
+
project_dir = Path(project_dir).absolute()
|
|
163
|
+
|
|
164
|
+
# Unload modules if the project directory has changed
|
|
165
|
+
if _current_sys_path and _current_sys_path != str(project_dir):
|
|
166
|
+
_unload_modules(Path(_current_sys_path))
|
|
167
|
+
|
|
168
|
+
# Set the system path
|
|
169
|
+
_set_sys_path(project_dir)
|
|
170
|
+
|
|
171
|
+
# Import the module
|
|
172
|
+
if module_str not in sys.modules:
|
|
173
|
+
module = importlib.import_module(module_str)
|
|
174
|
+
# Hack: `tabnet` does not work with `importlib.reload`
|
|
175
|
+
elif "tabnet" in sys.modules:
|
|
176
|
+
log(
|
|
177
|
+
WARN,
|
|
178
|
+
"Cannot reload module `%s` from disk due to compatibility issues "
|
|
179
|
+
"with the `tabnet` library. The module will be loaded from the "
|
|
180
|
+
"cache instead. If you experience issues, consider restarting "
|
|
181
|
+
"the application.",
|
|
182
|
+
module_str,
|
|
183
|
+
)
|
|
184
|
+
module = sys.modules[module_str]
|
|
185
|
+
else:
|
|
186
|
+
module = sys.modules[module_str]
|
|
187
|
+
_reload_modules(project_dir)
|
|
188
|
+
|
|
189
|
+
except ModuleNotFoundError as err:
|
|
190
|
+
raise error_type(
|
|
191
|
+
f"Unable to load module {module_str}{OBJECT_REF_HELP_STR}",
|
|
192
|
+
) from err
|
|
193
|
+
|
|
194
|
+
# Recursively load attribute
|
|
195
|
+
attribute = module
|
|
196
|
+
try:
|
|
197
|
+
for attribute_str in attributes_str.split("."):
|
|
198
|
+
attribute = getattr(attribute, attribute_str)
|
|
199
|
+
except AttributeError as err:
|
|
200
|
+
raise error_type(
|
|
201
|
+
f"Unable to load attribute {attributes_str} from module {module_str}"
|
|
202
|
+
f"{OBJECT_REF_HELP_STR}",
|
|
203
|
+
) from err
|
|
204
|
+
|
|
205
|
+
return attribute
|
|
203
206
|
|
|
204
207
|
|
|
205
208
|
def _unload_modules(project_dir: Path) -> None:
|
flwr/common/retry_invoker.py
CHANGED
|
@@ -20,8 +20,17 @@ import random
|
|
|
20
20
|
import time
|
|
21
21
|
from collections.abc import Generator, Iterable
|
|
22
22
|
from dataclasses import dataclass
|
|
23
|
+
from logging import INFO, WARN
|
|
23
24
|
from typing import Any, Callable, Optional, Union, cast
|
|
24
25
|
|
|
26
|
+
import grpc
|
|
27
|
+
|
|
28
|
+
from flwr.common.constant import MAX_RETRY_DELAY
|
|
29
|
+
from flwr.common.logger import log
|
|
30
|
+
from flwr.common.typing import RunNotRunningException
|
|
31
|
+
from flwr.proto.clientappio_pb2_grpc import ClientAppIoStub
|
|
32
|
+
from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub
|
|
33
|
+
|
|
25
34
|
|
|
26
35
|
def exponential(
|
|
27
36
|
base_delay: float = 1,
|
|
@@ -303,3 +312,69 @@ class RetryInvoker:
|
|
|
303
312
|
# Trigger success event
|
|
304
313
|
try_call_event_handler(self.on_success)
|
|
305
314
|
return ret
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _make_simple_grpc_retry_invoker() -> RetryInvoker:
|
|
318
|
+
"""Create a simple gRPC retry invoker."""
|
|
319
|
+
|
|
320
|
+
def _on_sucess(retry_state: RetryState) -> None:
|
|
321
|
+
if retry_state.tries > 1:
|
|
322
|
+
log(
|
|
323
|
+
INFO,
|
|
324
|
+
"Connection successful after %.2f seconds and %s tries.",
|
|
325
|
+
retry_state.elapsed_time,
|
|
326
|
+
retry_state.tries,
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
def _on_backoff(retry_state: RetryState) -> None:
|
|
330
|
+
if retry_state.tries == 1:
|
|
331
|
+
log(WARN, "Connection attempt failed, retrying...")
|
|
332
|
+
else:
|
|
333
|
+
log(
|
|
334
|
+
WARN,
|
|
335
|
+
"Connection attempt failed, retrying in %.2f seconds",
|
|
336
|
+
retry_state.actual_wait,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
def _on_giveup(retry_state: RetryState) -> None:
|
|
340
|
+
if retry_state.tries > 1:
|
|
341
|
+
log(
|
|
342
|
+
WARN,
|
|
343
|
+
"Giving up reconnection after %.2f seconds and %s tries.",
|
|
344
|
+
retry_state.elapsed_time,
|
|
345
|
+
retry_state.tries,
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
def _should_giveup_fn(e: Exception) -> bool:
|
|
349
|
+
if e.code() == grpc.StatusCode.PERMISSION_DENIED: # type: ignore
|
|
350
|
+
raise RunNotRunningException
|
|
351
|
+
if e.code() == grpc.StatusCode.UNAVAILABLE: # type: ignore
|
|
352
|
+
return False
|
|
353
|
+
return True
|
|
354
|
+
|
|
355
|
+
return RetryInvoker(
|
|
356
|
+
wait_gen_factory=lambda: exponential(max_delay=MAX_RETRY_DELAY),
|
|
357
|
+
recoverable_exceptions=grpc.RpcError,
|
|
358
|
+
max_tries=None,
|
|
359
|
+
max_time=None,
|
|
360
|
+
on_success=_on_sucess,
|
|
361
|
+
on_backoff=_on_backoff,
|
|
362
|
+
on_giveup=_on_giveup,
|
|
363
|
+
should_giveup=_should_giveup_fn,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def _wrap_stub(
|
|
368
|
+
stub: Union[ServerAppIoStub, ClientAppIoStub], retry_invoker: RetryInvoker
|
|
369
|
+
) -> None:
|
|
370
|
+
"""Wrap a gRPC stub with a retry invoker."""
|
|
371
|
+
|
|
372
|
+
def make_lambda(original_method: Any) -> Any:
|
|
373
|
+
return lambda *args, **kwargs: retry_invoker.invoke(
|
|
374
|
+
original_method, *args, **kwargs
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
for method_name in vars(stub):
|
|
378
|
+
method = getattr(stub, method_name)
|
|
379
|
+
if callable(method):
|
|
380
|
+
setattr(stub, method_name, make_lambda(method))
|
flwr/common/typing.py
CHANGED
flwr/proto/fab_pb2.py
CHANGED
|
@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
|
|
|
15
15
|
from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\"(\n\x03\x46\x61\x62\x12\x10\n\x08hash_str\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\x0c\"
|
|
18
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\"(\n\x03\x46\x61\x62\x12\x10\n\x08hash_str\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\x0c\"Q\n\rGetFabRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08hash_str\x18\x02 \x01(\t\x12\x0e\n\x06run_id\x18\x03 \x01(\x04\".\n\x0eGetFabResponse\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fabb\x06proto3')
|
|
19
19
|
|
|
20
20
|
_globals = globals()
|
|
21
21
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -25,7 +25,7 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
|
25
25
|
_globals['_FAB']._serialized_start=59
|
|
26
26
|
_globals['_FAB']._serialized_end=99
|
|
27
27
|
_globals['_GETFABREQUEST']._serialized_start=101
|
|
28
|
-
_globals['_GETFABREQUEST']._serialized_end=
|
|
29
|
-
_globals['_GETFABRESPONSE']._serialized_start=
|
|
30
|
-
_globals['_GETFABRESPONSE']._serialized_end=
|
|
28
|
+
_globals['_GETFABREQUEST']._serialized_end=182
|
|
29
|
+
_globals['_GETFABRESPONSE']._serialized_start=184
|
|
30
|
+
_globals['_GETFABRESPONSE']._serialized_end=230
|
|
31
31
|
# @@protoc_insertion_point(module_scope)
|
flwr/proto/fab_pb2.pyi
CHANGED
|
@@ -36,16 +36,19 @@ class GetFabRequest(google.protobuf.message.Message):
|
|
|
36
36
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
37
37
|
NODE_FIELD_NUMBER: builtins.int
|
|
38
38
|
HASH_STR_FIELD_NUMBER: builtins.int
|
|
39
|
+
RUN_ID_FIELD_NUMBER: builtins.int
|
|
39
40
|
@property
|
|
40
41
|
def node(self) -> flwr.proto.node_pb2.Node: ...
|
|
41
42
|
hash_str: typing.Text
|
|
43
|
+
run_id: builtins.int
|
|
42
44
|
def __init__(self,
|
|
43
45
|
*,
|
|
44
46
|
node: typing.Optional[flwr.proto.node_pb2.Node] = ...,
|
|
45
47
|
hash_str: typing.Text = ...,
|
|
48
|
+
run_id: builtins.int = ...,
|
|
46
49
|
) -> None: ...
|
|
47
50
|
def HasField(self, field_name: typing_extensions.Literal["node",b"node"]) -> builtins.bool: ...
|
|
48
|
-
def ClearField(self, field_name: typing_extensions.Literal["hash_str",b"hash_str","node",b"node"]) -> None: ...
|
|
51
|
+
def ClearField(self, field_name: typing_extensions.Literal["hash_str",b"hash_str","node",b"node","run_id",b"run_id"]) -> None: ...
|
|
49
52
|
global___GetFabRequest = GetFabRequest
|
|
50
53
|
|
|
51
54
|
class GetFabResponse(google.protobuf.message.Message):
|
flwr/server/compat/app_utils.py
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
import threading
|
|
19
19
|
|
|
20
|
+
from flwr.common.typing import RunNotRunningException
|
|
21
|
+
|
|
20
22
|
from ..client_manager import ClientManager
|
|
21
23
|
from ..compat.driver_client_proxy import DriverClientProxy
|
|
22
24
|
from ..driver import Driver
|
|
@@ -74,7 +76,11 @@ def _update_client_manager(
|
|
|
74
76
|
# Loop until the driver is disconnected
|
|
75
77
|
registered_nodes: dict[int, DriverClientProxy] = {}
|
|
76
78
|
while not f_stop.is_set():
|
|
77
|
-
|
|
79
|
+
try:
|
|
80
|
+
all_node_ids = set(driver.get_node_ids())
|
|
81
|
+
except RunNotRunningException:
|
|
82
|
+
f_stop.set()
|
|
83
|
+
break
|
|
78
84
|
dead_nodes = set(registered_nodes).difference(all_node_ids)
|
|
79
85
|
new_nodes = all_node_ids.difference(registered_nodes)
|
|
80
86
|
|
|
@@ -17,16 +17,16 @@
|
|
|
17
17
|
import time
|
|
18
18
|
import warnings
|
|
19
19
|
from collections.abc import Iterable
|
|
20
|
-
from logging import DEBUG,
|
|
21
|
-
from typing import
|
|
20
|
+
from logging import DEBUG, WARNING
|
|
21
|
+
from typing import Optional, cast
|
|
22
22
|
|
|
23
23
|
import grpc
|
|
24
24
|
|
|
25
25
|
from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
|
|
26
|
-
from flwr.common.constant import
|
|
26
|
+
from flwr.common.constant import SERVERAPPIO_API_DEFAULT_CLIENT_ADDRESS
|
|
27
27
|
from flwr.common.grpc import create_channel
|
|
28
28
|
from flwr.common.logger import log
|
|
29
|
-
from flwr.common.retry_invoker import
|
|
29
|
+
from flwr.common.retry_invoker import _make_simple_grpc_retry_invoker, _wrap_stub
|
|
30
30
|
from flwr.common.serde import message_from_taskres, message_to_taskins, run_from_proto
|
|
31
31
|
from flwr.common.typing import Run
|
|
32
32
|
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
|
@@ -262,60 +262,3 @@ class GrpcDriver(Driver):
|
|
|
262
262
|
return
|
|
263
263
|
# Disconnect
|
|
264
264
|
self._disconnect()
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
def _make_simple_grpc_retry_invoker() -> RetryInvoker:
|
|
268
|
-
"""Create a simple gRPC retry invoker."""
|
|
269
|
-
|
|
270
|
-
def _on_sucess(retry_state: RetryState) -> None:
|
|
271
|
-
if retry_state.tries > 1:
|
|
272
|
-
log(
|
|
273
|
-
INFO,
|
|
274
|
-
"Connection successful after %.2f seconds and %s tries.",
|
|
275
|
-
retry_state.elapsed_time,
|
|
276
|
-
retry_state.tries,
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
def _on_backoff(retry_state: RetryState) -> None:
|
|
280
|
-
if retry_state.tries == 1:
|
|
281
|
-
log(WARN, "Connection attempt failed, retrying...")
|
|
282
|
-
else:
|
|
283
|
-
log(
|
|
284
|
-
WARN,
|
|
285
|
-
"Connection attempt failed, retrying in %.2f seconds",
|
|
286
|
-
retry_state.actual_wait,
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
def _on_giveup(retry_state: RetryState) -> None:
|
|
290
|
-
if retry_state.tries > 1:
|
|
291
|
-
log(
|
|
292
|
-
WARN,
|
|
293
|
-
"Giving up reconnection after %.2f seconds and %s tries.",
|
|
294
|
-
retry_state.elapsed_time,
|
|
295
|
-
retry_state.tries,
|
|
296
|
-
)
|
|
297
|
-
|
|
298
|
-
return RetryInvoker(
|
|
299
|
-
wait_gen_factory=lambda: exponential(max_delay=MAX_RETRY_DELAY),
|
|
300
|
-
recoverable_exceptions=grpc.RpcError,
|
|
301
|
-
max_tries=None,
|
|
302
|
-
max_time=None,
|
|
303
|
-
on_success=_on_sucess,
|
|
304
|
-
on_backoff=_on_backoff,
|
|
305
|
-
on_giveup=_on_giveup,
|
|
306
|
-
should_giveup=lambda e: e.code() != grpc.StatusCode.UNAVAILABLE, # type: ignore
|
|
307
|
-
)
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
def _wrap_stub(stub: ServerAppIoStub, retry_invoker: RetryInvoker) -> None:
|
|
311
|
-
"""Wrap the gRPC stub with a retry invoker."""
|
|
312
|
-
|
|
313
|
-
def make_lambda(original_method: Any) -> Any:
|
|
314
|
-
return lambda *args, **kwargs: retry_invoker.invoke(
|
|
315
|
-
original_method, *args, **kwargs
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
for method_name in vars(stub):
|
|
319
|
-
method = getattr(stub, method_name)
|
|
320
|
-
if callable(method):
|
|
321
|
-
setattr(stub, method_name, make_lambda(method))
|
flwr/server/serverapp/app.py
CHANGED
|
@@ -50,7 +50,7 @@ from flwr.common.serde import (
|
|
|
50
50
|
run_from_proto,
|
|
51
51
|
run_status_to_proto,
|
|
52
52
|
)
|
|
53
|
-
from flwr.common.typing import RunStatus
|
|
53
|
+
from flwr.common.typing import RunNotRunningException, RunStatus
|
|
54
54
|
from flwr.proto.run_pb2 import UpdateRunStatusRequest # pylint: disable=E0611
|
|
55
55
|
from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
|
|
56
56
|
PullServerAppInputsRequest,
|
|
@@ -96,7 +96,7 @@ def flwr_serverapp() -> None:
|
|
|
96
96
|
restore_output()
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
def run_serverapp( # pylint: disable=R0914, disable=W0212
|
|
99
|
+
def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
|
|
100
100
|
serverappio_api_address: str,
|
|
101
101
|
log_queue: Queue[Optional[str]],
|
|
102
102
|
run_once: bool,
|
|
@@ -187,6 +187,12 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212
|
|
|
187
187
|
|
|
188
188
|
run_status = RunStatus(Status.FINISHED, SubStatus.COMPLETED, "")
|
|
189
189
|
|
|
190
|
+
except RunNotRunningException:
|
|
191
|
+
log(INFO, "")
|
|
192
|
+
log(INFO, "Run ID %s stopped.", run.run_id)
|
|
193
|
+
log(INFO, "")
|
|
194
|
+
run_status = None
|
|
195
|
+
|
|
190
196
|
except Exception as ex: # pylint: disable=broad-exception-caught
|
|
191
197
|
exc_entity = "ServerApp"
|
|
192
198
|
log(ERROR, "%s raised an exception", exc_entity, exc_info=ex)
|
|
@@ -70,6 +70,7 @@ from flwr.proto.task_pb2 import TaskRes # pylint: disable=E0611
|
|
|
70
70
|
from flwr.server.superlink.ffs.ffs import Ffs
|
|
71
71
|
from flwr.server.superlink.ffs.ffs_factory import FfsFactory
|
|
72
72
|
from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
|
|
73
|
+
from flwr.server.superlink.utils import abort_if
|
|
73
74
|
from flwr.server.utils.validator import validate_task_ins_or_res
|
|
74
75
|
|
|
75
76
|
|
|
@@ -88,7 +89,18 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
|
88
89
|
) -> GetNodesResponse:
|
|
89
90
|
"""Get available nodes."""
|
|
90
91
|
log(DEBUG, "ServerAppIoServicer.GetNodes")
|
|
92
|
+
|
|
93
|
+
# Init state
|
|
91
94
|
state: LinkState = self.state_factory.state()
|
|
95
|
+
|
|
96
|
+
# Abort if the run is not running
|
|
97
|
+
abort_if(
|
|
98
|
+
request.run_id,
|
|
99
|
+
[Status.PENDING, Status.STARTING, Status.FINISHED],
|
|
100
|
+
state,
|
|
101
|
+
context,
|
|
102
|
+
)
|
|
103
|
+
|
|
92
104
|
all_ids: set[int] = state.get_nodes(request.run_id)
|
|
93
105
|
nodes: list[Node] = [
|
|
94
106
|
Node(node_id=node_id, anonymous=False) for node_id in all_ids
|
|
@@ -126,6 +138,17 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
|
126
138
|
"""Push a set of TaskIns."""
|
|
127
139
|
log(DEBUG, "ServerAppIoServicer.PushTaskIns")
|
|
128
140
|
|
|
141
|
+
# Init state
|
|
142
|
+
state: LinkState = self.state_factory.state()
|
|
143
|
+
|
|
144
|
+
# Abort if the run is not running
|
|
145
|
+
abort_if(
|
|
146
|
+
request.run_id,
|
|
147
|
+
[Status.PENDING, Status.STARTING, Status.FINISHED],
|
|
148
|
+
state,
|
|
149
|
+
context,
|
|
150
|
+
)
|
|
151
|
+
|
|
129
152
|
# Set pushed_at (timestamp in seconds)
|
|
130
153
|
pushed_at = time.time()
|
|
131
154
|
for task_ins in request.task_ins_list:
|
|
@@ -137,9 +160,6 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
|
137
160
|
validation_errors = validate_task_ins_or_res(task_ins)
|
|
138
161
|
_raise_if(bool(validation_errors), ", ".join(validation_errors))
|
|
139
162
|
|
|
140
|
-
# Init state
|
|
141
|
-
state: LinkState = self.state_factory.state()
|
|
142
|
-
|
|
143
163
|
# Store each TaskIns
|
|
144
164
|
task_ids: list[Optional[UUID]] = []
|
|
145
165
|
for task_ins in request.task_ins_list:
|
|
@@ -156,12 +176,20 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
|
156
176
|
"""Pull a set of TaskRes."""
|
|
157
177
|
log(DEBUG, "ServerAppIoServicer.PullTaskRes")
|
|
158
178
|
|
|
159
|
-
# Convert each task_id str to UUID
|
|
160
|
-
task_ids: set[UUID] = {UUID(task_id) for task_id in request.task_ids}
|
|
161
|
-
|
|
162
179
|
# Init state
|
|
163
180
|
state: LinkState = self.state_factory.state()
|
|
164
181
|
|
|
182
|
+
# Abort if the run is not running
|
|
183
|
+
abort_if(
|
|
184
|
+
request.run_id,
|
|
185
|
+
[Status.PENDING, Status.STARTING, Status.FINISHED],
|
|
186
|
+
state,
|
|
187
|
+
context,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Convert each task_id str to UUID
|
|
191
|
+
task_ids: set[UUID] = {UUID(task_id) for task_id in request.task_ids}
|
|
192
|
+
|
|
165
193
|
# Register callback
|
|
166
194
|
def on_rpc_done() -> None:
|
|
167
195
|
log(
|
|
@@ -258,7 +286,18 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
|
258
286
|
) -> PushServerAppOutputsResponse:
|
|
259
287
|
"""Push ServerApp process outputs."""
|
|
260
288
|
log(DEBUG, "ServerAppIoServicer.PushServerAppOutputs")
|
|
289
|
+
|
|
290
|
+
# Init state
|
|
261
291
|
state = self.state_factory.state()
|
|
292
|
+
|
|
293
|
+
# Abort if the run is not running
|
|
294
|
+
abort_if(
|
|
295
|
+
request.run_id,
|
|
296
|
+
[Status.PENDING, Status.STARTING, Status.FINISHED],
|
|
297
|
+
state,
|
|
298
|
+
context,
|
|
299
|
+
)
|
|
300
|
+
|
|
262
301
|
state.set_serverapp_context(request.run_id, context_from_proto(request.context))
|
|
263
302
|
return PushServerAppOutputsResponse()
|
|
264
303
|
|
|
@@ -267,8 +306,13 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
|
267
306
|
) -> UpdateRunStatusResponse:
|
|
268
307
|
"""Update the status of a run."""
|
|
269
308
|
log(DEBUG, "ServerAppIoServicer.UpdateRunStatus")
|
|
309
|
+
|
|
310
|
+
# Init state
|
|
270
311
|
state = self.state_factory.state()
|
|
271
312
|
|
|
313
|
+
# Abort if the run is finished
|
|
314
|
+
abort_if(request.run_id, [Status.FINISHED], state, context)
|
|
315
|
+
|
|
272
316
|
# Update the run status
|
|
273
317
|
state.update_run_status(
|
|
274
318
|
run_id=request.run_id, new_status=run_status_from_proto(request.run_status)
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
"""SuperLink utilities."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from typing import Union
|
|
19
|
+
|
|
20
|
+
import grpc
|
|
21
|
+
|
|
22
|
+
from flwr.common.constant import Status, SubStatus
|
|
23
|
+
from flwr.common.typing import RunStatus
|
|
24
|
+
from flwr.server.superlink.linkstate import LinkState
|
|
25
|
+
|
|
26
|
+
_STATUS_TO_MSG = {
|
|
27
|
+
Status.PENDING: "Run is pending.",
|
|
28
|
+
Status.STARTING: "Run is starting.",
|
|
29
|
+
Status.RUNNING: "Run is running.",
|
|
30
|
+
Status.FINISHED: "Run is finished.",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def check_abort(
|
|
35
|
+
run_id: int,
|
|
36
|
+
abort_status_list: list[str],
|
|
37
|
+
state: LinkState,
|
|
38
|
+
) -> Union[str, None]:
|
|
39
|
+
"""Check if the status of the provided `run_id` is in `abort_status_list`."""
|
|
40
|
+
run_status: RunStatus = state.get_run_status({run_id})[run_id]
|
|
41
|
+
|
|
42
|
+
if run_status.status in abort_status_list:
|
|
43
|
+
msg = _STATUS_TO_MSG[run_status.status]
|
|
44
|
+
if run_status.sub_status == SubStatus.STOPPED:
|
|
45
|
+
msg += " Stopped by user."
|
|
46
|
+
return msg
|
|
47
|
+
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def abort_grpc_context(msg: Union[str, None], context: grpc.ServicerContext) -> None:
|
|
52
|
+
"""Abort context with statuscode PERMISSION_DENIED if `msg` is not None."""
|
|
53
|
+
if msg is not None:
|
|
54
|
+
context.abort(grpc.StatusCode.PERMISSION_DENIED, msg)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def abort_if(
|
|
58
|
+
run_id: int,
|
|
59
|
+
abort_status_list: list[str],
|
|
60
|
+
state: LinkState,
|
|
61
|
+
context: grpc.ServicerContext,
|
|
62
|
+
) -> None:
|
|
63
|
+
"""Abort context if status of the provided `run_id` is in `abort_status_list`."""
|
|
64
|
+
msg = check_abort(run_id, abort_status_list, state)
|
|
65
|
+
abort_grpc_context(msg, context)
|
{flwr_nightly-1.14.0.dev20241211.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/RECORD
RENAMED
|
@@ -11,7 +11,7 @@ flwr/cli/login/__init__.py,sha256=PEh6QjLSx7ltN8d8Jfi25dHFPKtCNKjYJZCkYQBfmm0,79
|
|
|
11
11
|
flwr/cli/login/login.py,sha256=GVm6rkLDVQ6WuT2mw52gBKNW_Y5IjGg_OOGoEmpx9KM,2796
|
|
12
12
|
flwr/cli/ls.py,sha256=5uO0YG0XXn7paS4oUs1T7rwicApxMV3ac9ejBZfLN3k,10545
|
|
13
13
|
flwr/cli/new/__init__.py,sha256=cQzK1WH4JP2awef1t2UQ2xjl1agVEz9rwutV18SWV1k,789
|
|
14
|
-
flwr/cli/new/new.py,sha256=
|
|
14
|
+
flwr/cli/new/new.py,sha256=AoGfQl_IPN6LwZBYPgRAMgME5BODsL3n1OtErSEVVkc,9921
|
|
15
15
|
flwr/cli/new/templates/__init__.py,sha256=4luU8RL-CK8JJCstQ_ON809W9bNTkY1l9zSaPKBkgwY,725
|
|
16
16
|
flwr/cli/new/templates/app/.gitignore.tpl,sha256=XixnHdyeMB2vwkGtGnwHqoWpH-9WChdyG0GXe57duhc,3078
|
|
17
17
|
flwr/cli/new/templates/app/LICENSE.tpl,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
|
@@ -59,7 +59,7 @@ flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=_bT_ze1QPajyFZW0Ax
|
|
|
59
59
|
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=WHLdFbHhfs3ZmLCG5pa5TUKFoRV67TT1J1SXMM0zStY,1873
|
|
60
60
|
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=_LSCSc9cAiRuvTLdsy9wphwzhV7FCOUxO1ce12YOk58,1143
|
|
61
61
|
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=8xC1457V13AxTsO7SaLsqhQQPN7Aau3wbNZqKJ9Inx8,673
|
|
62
|
-
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=
|
|
62
|
+
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=sJMPYaroZLM7EkIX5ulnCelKxHlpViYiSqhswEnGrB0,744
|
|
63
63
|
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=SbCIUjwCIsgTRoBb-GMwivcWdoigMvD3QbKL6TJNgWM,612
|
|
64
64
|
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=UtH3Vslg2S8fIKIHC-dJGcxz5YUK2WI3F2TUAgTsQn0,710
|
|
65
65
|
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=01HArBqRrbZT3O7pXOM9MqduXMNm525wv7Sj6dvYMJE,686
|
|
@@ -92,7 +92,7 @@ flwr/client/message_handler/task_handler.py,sha256=ZDJBKmrn2grRMNl1rU1iGs7FiMHL5
|
|
|
92
92
|
flwr/client/mod/__init__.py,sha256=37XeXZLFq_tzFVKVtC9JaigM2bSAU7BrGQvMPCE3Q28,1159
|
|
93
93
|
flwr/client/mod/centraldp_mods.py,sha256=UGwNuqpmOWfLdfJITFgdi1TG-nLjuSb-cbEyoyfDgxQ,5415
|
|
94
94
|
flwr/client/mod/comms_mods.py,sha256=QzJF7lgbYGnZvY805rkBfDsYCRC0HBHeDkJQ_JXhUZY,2624
|
|
95
|
-
flwr/client/mod/localdp_mod.py,sha256=
|
|
95
|
+
flwr/client/mod/localdp_mod.py,sha256=Zhcu2M1QYCaS0dfmTjkhmFABIJcFXfT6zDgV0o9sn-4,5003
|
|
96
96
|
flwr/client/mod/secure_aggregation/__init__.py,sha256=A7DzZ3uvXTUkuHBzrxJMWQQD4RtO_PsVA53yHc4oWco,849
|
|
97
97
|
flwr/client/mod/secure_aggregation/secagg_mod.py,sha256=wI9tuIEvMUETz-wVIEbPYvh-1nK9CEylBLGoVpNhL94,1095
|
|
98
98
|
flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=7cNXsY07ZA0M5_9VSc52F8JUoAoGaraNDA2rgaLvvFo,19680
|
|
@@ -124,7 +124,7 @@ flwr/common/exit_handlers.py,sha256=MracJaBeoCOC7TaXK9zCJQxhrMSx9ZtczK237qvhBpU,
|
|
|
124
124
|
flwr/common/grpc.py,sha256=AIPMAHsvcTlduaYKCgnoBnst1A7RZEgGqh0Ulm7qfJ0,2621
|
|
125
125
|
flwr/common/logger.py,sha256=NQkdrtAP3NFTH_ebTTrjD2z6y-1bdoiIx9_npC-1TWw,11940
|
|
126
126
|
flwr/common/message.py,sha256=4O1m0OWXBAYZz05gKgEtnoJ94J1gjo7hCNHyUXThxRo,13831
|
|
127
|
-
flwr/common/object_ref.py,sha256=
|
|
127
|
+
flwr/common/object_ref.py,sha256=fIXf8aP5mG6Nuni7dvcKK5Di3zRfRWGs4ljvqIXplds,10115
|
|
128
128
|
flwr/common/parameter.py,sha256=-bFAUayToYDF50FZGrBC1hQYJCQDtB2bbr3ZuVLMtdE,2095
|
|
129
129
|
flwr/common/pyproject.py,sha256=EI_ovbCHGmhYrdPx0RSDi5EkFZFof-8m1PA54c0ZTjc,1385
|
|
130
130
|
flwr/common/record/__init__.py,sha256=ejDBQOIA0OkwZAC5cK_tTPHA4oAM0Ju7Oi13-NneMlE,1054
|
|
@@ -135,7 +135,7 @@ flwr/common/record/parametersrecord.py,sha256=IjnewX8Ea6JXLRWcPMVole2sNjwzRVjBVv
|
|
|
135
135
|
flwr/common/record/recordset.py,sha256=sSofrBycZSqiHR4TzfI4_QoIIN-5B1LnMG0C9CiByAo,8312
|
|
136
136
|
flwr/common/record/typeddict.py,sha256=q5hL2xkXymuiCprHWb69mUmLpWQk_XXQq0hGQ69YPaw,3599
|
|
137
137
|
flwr/common/recordset_compat.py,sha256=ViSwA26h6Q55ZmV1LLjSJpcKiipV-p_JpCj4wxdE-Ow,14230
|
|
138
|
-
flwr/common/retry_invoker.py,sha256=
|
|
138
|
+
flwr/common/retry_invoker.py,sha256=nCA-dfBw6YoWkOgop71QfhTDmYj1JIgXsdpzlyqgZK4,14396
|
|
139
139
|
flwr/common/secure_aggregation/__init__.py,sha256=erPnTWdOfMH0K0HQTmj5foDJ6t3iYcExy2aACy8iZNQ,731
|
|
140
140
|
flwr/common/secure_aggregation/crypto/__init__.py,sha256=nlHesCWy8xxE5s6qHWnauCtyClcMQ2K0CEXAHakY5n0,738
|
|
141
141
|
flwr/common/secure_aggregation/crypto/shamir.py,sha256=wCSfEfeaPgJ9Om580-YPUF2ljiyRhq33TRC4HtwxYl8,2779
|
|
@@ -146,7 +146,7 @@ flwr/common/secure_aggregation/secaggplus_constants.py,sha256=9MF-oQh62uD7rt9VeN
|
|
|
146
146
|
flwr/common/secure_aggregation/secaggplus_utils.py,sha256=OgYd68YBRaHQYLc-YdExj9CSpwL58bVTaPrdHoAj2AE,3214
|
|
147
147
|
flwr/common/serde.py,sha256=K9ExsqcTPETESkt2HMaNtIQAIAfwmuwtJFlG-59I7Sw,31046
|
|
148
148
|
flwr/common/telemetry.py,sha256=CHIwFFQ13sWFavmEvkvA43XR1sbh1S3nWvD5TuCO2eI,8774
|
|
149
|
-
flwr/common/typing.py,sha256=
|
|
149
|
+
flwr/common/typing.py,sha256=Ux8rJllzqORzCiv9HYkqVVyEzmd3nOKbcmttj5d2P_I,5801
|
|
150
150
|
flwr/common/version.py,sha256=tCcl_FvxVK206C1dxIJCs4TjL06WmyaODBP19FRHE1c,1324
|
|
151
151
|
flwr/proto/__init__.py,sha256=hbY7JYakwZwCkYgCNlmHdc8rtvfoJbAZLalMdc--CGc,683
|
|
152
152
|
flwr/proto/clientappio_pb2.py,sha256=Y3PMv-JMaBGehpslgbvGY6l2u5vNpfCTFWu-fmAmBJ4,3703
|
|
@@ -161,8 +161,8 @@ flwr/proto/exec_pb2.py,sha256=IVqmpzzThSjuLBCF8T9VofTpnUXtp3SYWOEp8dzyv5o,6883
|
|
|
161
161
|
flwr/proto/exec_pb2.pyi,sha256=amt-3e3zJVjkRlQ8Gz6m1A7hXyeZmbQhHpAEIQyIDn0,10660
|
|
162
162
|
flwr/proto/exec_pb2_grpc.py,sha256=-bdLqjsqQxK9R8LIiZaKlLKH2NmjR50EaGKTPPTwFhI,10445
|
|
163
163
|
flwr/proto/exec_pb2_grpc.pyi,sha256=M5k-FzeLWxal7zt28LJfzMWWRxmNknTC2BzHRRMa1sQ,2914
|
|
164
|
-
flwr/proto/fab_pb2.py,sha256
|
|
165
|
-
flwr/proto/fab_pb2.pyi,sha256=
|
|
164
|
+
flwr/proto/fab_pb2.py,sha256=-gfW_ePYHx1vDGHfimwn91qEhmmY_gslaOHwqqZnVdU,1627
|
|
165
|
+
flwr/proto/fab_pb2.pyi,sha256=AMXpiDK0fo3nZWjxsC2E4otSaVjyQbU7iiWKrsSZavs,2395
|
|
166
166
|
flwr/proto/fab_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
|
167
167
|
flwr/proto/fab_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
|
|
168
168
|
flwr/proto/fleet_pb2.py,sha256=06NAaIAOxTA2UhkBA-VWZKflaVQIzXgPZ3Fb6vtliY0,4789
|
|
@@ -216,13 +216,13 @@ flwr/server/client_manager.py,sha256=7Ese0tgrH-i-ms363feYZJKwB8gWnXSmg_hYF2Bju4U
|
|
|
216
216
|
flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
|
|
217
217
|
flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
|
|
218
218
|
flwr/server/compat/app.py,sha256=5vkHHm_h-4cMthvWD1GJo1ZW3eihytjGgvsgfXUK9gA,3298
|
|
219
|
-
flwr/server/compat/app_utils.py,sha256=
|
|
219
|
+
flwr/server/compat/app_utils.py,sha256=ha1K9h4KfM80-Bcluwa_LtBfQ5g643Eb_QfaAm-GmTU,3579
|
|
220
220
|
flwr/server/compat/driver_client_proxy.py,sha256=Af0bRUEVZNcCYRxt3DjpLPdvVYpTgz6LSlILtI_8DQY,5010
|
|
221
221
|
flwr/server/compat/legacy_context.py,sha256=wBzBcfV6YO6IQGriM_FdJ5XZfiBBEEJdS_OdAiF47dY,1804
|
|
222
222
|
flwr/server/criterion.py,sha256=ypbAexbztzGUxNen9RCHF91QeqiEQix4t4Ih3E-42MM,1061
|
|
223
223
|
flwr/server/driver/__init__.py,sha256=bikRv6CjTwSvYh7tf10gziU5o2YotOWhhftz2tr3KDc,886
|
|
224
224
|
flwr/server/driver/driver.py,sha256=u_fMfqLYTroTafGCNwKPHI4lttRL-Z5CqeT3_FHSq-Q,5701
|
|
225
|
-
flwr/server/driver/grpc_driver.py,sha256=
|
|
225
|
+
flwr/server/driver/grpc_driver.py,sha256=KXe_zlwwzgnawkeYFNVo8Tq45CGGmMFBAerqxso-s-E,9635
|
|
226
226
|
flwr/server/driver/inmemory_driver.py,sha256=gfB4jmkk1indhRa9XCdKCXghVcWBF1qBD-tAxMUyQm0,6404
|
|
227
227
|
flwr/server/history.py,sha256=qSb5_pPTrwofpSYGsZWzMPkl_4uJ4mJFWesxXDrEvDU,5026
|
|
228
228
|
flwr/server/run_serverapp.py,sha256=oDfHaHyVT5BRcckFFQKg8AVPCWR1ek7OhNceTC8qq9g,2493
|
|
@@ -230,7 +230,7 @@ flwr/server/server.py,sha256=1ZsFEptmAV-L2vP2etNC9Ed5CLSxpuKzUFkAPQ4l5Xc,17893
|
|
|
230
230
|
flwr/server/server_app.py,sha256=RsgS6PRS5Z74cMUAHzsm8r3LWddwn00MjRs6rlacHt8,6297
|
|
231
231
|
flwr/server/server_config.py,sha256=CZaHVAsMvGLjpWVcLPkiYxgJN4xfIyAiUrCI3fETKY4,1349
|
|
232
232
|
flwr/server/serverapp/__init__.py,sha256=L0K-94UDdTyEZ8LDtYybGIIIv3HW6AhSVjXMUfYJQnQ,800
|
|
233
|
-
flwr/server/serverapp/app.py,sha256=
|
|
233
|
+
flwr/server/serverapp/app.py,sha256=E35c-Ic8l9gH463nRBQlMxamJ72Ng-ka4jGWDkwlK_U,7910
|
|
234
234
|
flwr/server/serverapp_components.py,sha256=-IV_CitOfrJclJj2jNdbN1Q65PyFmtKtrTIg1hc6WQw,2118
|
|
235
235
|
flwr/server/strategy/__init__.py,sha256=tQer2SwjDnvgFFuJMZM-S01Z615N5XK6MaCvpm4BMU0,2836
|
|
236
236
|
flwr/server/strategy/aggregate.py,sha256=PDvekufza13s9AsVmz9WASunaBs3yCtl8JVliFx9j6Q,13978
|
|
@@ -259,7 +259,7 @@ flwr/server/strategy/strategy.py,sha256=cXapkD5uDrt5C-RbmWDn9FLoap3Q41i7GKvbmfbC
|
|
|
259
259
|
flwr/server/superlink/__init__.py,sha256=8tHYCfodUlRD8PCP9fHgvu8cz5N31A2QoRVL0jDJ15E,707
|
|
260
260
|
flwr/server/superlink/driver/__init__.py,sha256=5soEK5QSvxNjmJQ-CGTWROc4alSAeU0e9Ad9RDhsd3E,717
|
|
261
261
|
flwr/server/superlink/driver/serverappio_grpc.py,sha256=oTogZLkfeThKdx9Q_bw6OMGHnLIryxQOHxbWi0qgaRM,2185
|
|
262
|
-
flwr/server/superlink/driver/serverappio_servicer.py,sha256=
|
|
262
|
+
flwr/server/superlink/driver/serverappio_servicer.py,sha256=As8Ow1Dmv4tTiuCMTtokE66kGZr8BTN0fd6EgT_XkLs,12161
|
|
263
263
|
flwr/server/superlink/ffs/__init__.py,sha256=FAY-zShcfPmOxosok2QyT6hTNMNctG8cH9s_nIl8jkI,840
|
|
264
264
|
flwr/server/superlink/ffs/disk_ffs.py,sha256=yCN6CCzegnJIOaHr5nIu49wZQa4g5BByiSKshz50RKU,3296
|
|
265
265
|
flwr/server/superlink/ffs/ffs.py,sha256=qLI1UfosJugu2BKOJWqHIhafTm-YiuKqGf3OGWPH0NM,2395
|
|
@@ -293,6 +293,7 @@ flwr/server/superlink/linkstate/utils.py,sha256=d5uqqIOCKfd54X8CFNfUr3AWqPLpgmzs
|
|
|
293
293
|
flwr/server/superlink/simulation/__init__.py,sha256=mg-oapC9dkzEfjXPQFior5lpWj4g9kwbLovptyYM_g0,718
|
|
294
294
|
flwr/server/superlink/simulation/simulationio_grpc.py,sha256=5wflYW_TS0mjmPG6OYuHMJwXD2_cYmUNhFkdOU0jMWQ,2237
|
|
295
295
|
flwr/server/superlink/simulation/simulationio_servicer.py,sha256=riaZm090aTs7o8cFD8gvCWkX7A2SPLXKM4K8MG60av8,6545
|
|
296
|
+
flwr/server/superlink/utils.py,sha256=KVb3K_g2vYfu9TnftcN0ewmev133WZcjuEePMm8d7GE,2137
|
|
296
297
|
flwr/server/typing.py,sha256=5kaRLZuxTEse9A0g7aVna2VhYxU3wTq1f3d3mtw7kXs,1019
|
|
297
298
|
flwr/server/utils/__init__.py,sha256=pltsPHJoXmUIr3utjwwYxu7_ZAGy5u4MVHzv9iA5Un8,908
|
|
298
299
|
flwr/server/utils/tensorboard.py,sha256=gEBD8w_5uaIfp5aw5RYH66lYZpd_SfkObHQ7eDd9MUk,5466
|
|
@@ -320,8 +321,8 @@ flwr/superexec/exec_servicer.py,sha256=jEYcASzkQR1ftjzilmlcTPKXo8NSno9mSj_UbBvMj
|
|
|
320
321
|
flwr/superexec/exec_user_auth_interceptor.py,sha256=K06OU-l4LnYhTDg071hGJuOaQWEJbZsYi5qxUmmtiG0,3704
|
|
321
322
|
flwr/superexec/executor.py,sha256=zH3_53il6Jh0ZscIVEB9f4GNnXMeBbCGyCoBCxLgiG0,3114
|
|
322
323
|
flwr/superexec/simulation.py,sha256=WQDon15oqpMopAZnwRZoTICYCfHqtkvFSqiTQ2hLD_g,4088
|
|
323
|
-
flwr_nightly-1.14.0.
|
|
324
|
-
flwr_nightly-1.14.0.
|
|
325
|
-
flwr_nightly-1.14.0.
|
|
326
|
-
flwr_nightly-1.14.0.
|
|
327
|
-
flwr_nightly-1.14.0.
|
|
324
|
+
flwr_nightly-1.14.0.dev20241212.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
325
|
+
flwr_nightly-1.14.0.dev20241212.dist-info/METADATA,sha256=IHpu3jP8Tt8KxOP3b4XtkPPf3wRSXYzwknPGE7mDlAY,15799
|
|
326
|
+
flwr_nightly-1.14.0.dev20241212.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
327
|
+
flwr_nightly-1.14.0.dev20241212.dist-info/entry_points.txt,sha256=JlNxX3qhaV18_2yj5a3kJW1ESxm31cal9iS_N_pf1Rk,538
|
|
328
|
+
flwr_nightly-1.14.0.dev20241212.dist-info/RECORD,,
|
{flwr_nightly-1.14.0.dev20241211.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/LICENSE
RENAMED
|
File without changes
|
{flwr_nightly-1.14.0.dev20241211.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|