flwr-nightly 1.17.0.dev20250312__py3-none-any.whl → 1.17.0.dev20250313__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/common/constant.py +0 -6
- flwr/common/event_log_plugin/event_log_plugin.py +2 -2
- flwr/server/app.py +55 -0
- flwr/server/fleet_event_log_interceptor.py +94 -0
- flwr/superexec/exec_grpc.py +10 -4
- {flwr_nightly-1.17.0.dev20250312.dist-info → flwr_nightly-1.17.0.dev20250313.dist-info}/METADATA +1 -1
- {flwr_nightly-1.17.0.dev20250312.dist-info → flwr_nightly-1.17.0.dev20250313.dist-info}/RECORD +10 -9
- {flwr_nightly-1.17.0.dev20250312.dist-info → flwr_nightly-1.17.0.dev20250313.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.17.0.dev20250312.dist-info → flwr_nightly-1.17.0.dev20250313.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.17.0.dev20250312.dist-info → flwr_nightly-1.17.0.dev20250313.dist-info}/entry_points.txt +0 -0
flwr/common/constant.py
CHANGED
@@ -217,14 +217,8 @@ class AuthType:
|
|
217
217
|
class EventLogWriterType:
|
218
218
|
"""Event log writer types."""
|
219
219
|
|
220
|
-
FALSE = "false"
|
221
220
|
STDOUT = "stdout"
|
222
221
|
|
223
222
|
def __new__(cls) -> EventLogWriterType:
|
224
223
|
"""Prevent instantiation."""
|
225
224
|
raise TypeError(f"{cls.__name__} cannot be instantiated.")
|
226
|
-
|
227
|
-
@classmethod
|
228
|
-
def choices(cls) -> list[str]:
|
229
|
-
"""Return a list of available log writer choices."""
|
230
|
-
return [cls.FALSE, cls.STDOUT]
|
@@ -36,7 +36,7 @@ class EventLogWriterPlugin(ABC):
|
|
36
36
|
self,
|
37
37
|
request: GrpcMessage,
|
38
38
|
context: grpc.ServicerContext,
|
39
|
-
user_info: UserInfo,
|
39
|
+
user_info: Optional[UserInfo],
|
40
40
|
method_name: str,
|
41
41
|
) -> LogEntry:
|
42
42
|
"""Compose pre-event log entry from the provided request and context."""
|
@@ -46,7 +46,7 @@ class EventLogWriterPlugin(ABC):
|
|
46
46
|
self,
|
47
47
|
request: GrpcMessage,
|
48
48
|
context: grpc.ServicerContext,
|
49
|
-
user_info: UserInfo,
|
49
|
+
user_info: Optional[UserInfo],
|
50
50
|
method_name: str,
|
51
51
|
response: Optional[Union[GrpcMessage, Exception]],
|
52
52
|
) -> LogEntry:
|
flwr/server/app.py
CHANGED
@@ -54,7 +54,9 @@ from flwr.common.constant import (
|
|
54
54
|
TRANSPORT_TYPE_GRPC_ADAPTER,
|
55
55
|
TRANSPORT_TYPE_GRPC_RERE,
|
56
56
|
TRANSPORT_TYPE_REST,
|
57
|
+
EventLogWriterType,
|
57
58
|
)
|
59
|
+
from flwr.common.event_log_plugin import EventLogWriterPlugin
|
58
60
|
from flwr.common.exit import ExitCode, flwr_exit
|
59
61
|
from flwr.common.exit_handlers import register_exit_handlers
|
60
62
|
from flwr.common.grpc import generic_create_grpc_server
|
@@ -66,6 +68,7 @@ from flwr.proto.fleet_pb2_grpc import ( # pylint: disable=E0611
|
|
66
68
|
add_FleetServicer_to_server,
|
67
69
|
)
|
68
70
|
from flwr.proto.grpcadapter_pb2_grpc import add_GrpcAdapterServicer_to_server
|
71
|
+
from flwr.server.fleet_event_log_interceptor import FleetEventLogInterceptor
|
69
72
|
from flwr.server.serverapp.app import flwr_serverapp
|
70
73
|
from flwr.simulation.app import flwr_simulation
|
71
74
|
from flwr.superexec.app import load_executor
|
@@ -94,6 +97,8 @@ try:
|
|
94
97
|
add_ee_args_superlink,
|
95
98
|
get_dashboard_server,
|
96
99
|
get_exec_auth_plugins,
|
100
|
+
get_exec_event_log_writer_plugins,
|
101
|
+
get_fleet_event_log_writer_plugins,
|
97
102
|
)
|
98
103
|
except ImportError:
|
99
104
|
|
@@ -105,6 +110,18 @@ except ImportError:
|
|
105
110
|
"""Return all Exec API authentication plugins."""
|
106
111
|
raise NotImplementedError("No authentication plugins are currently supported.")
|
107
112
|
|
113
|
+
def get_exec_event_log_writer_plugins() -> dict[str, type[EventLogWriterPlugin]]:
|
114
|
+
"""Return all Exec API event log writer plugins."""
|
115
|
+
raise NotImplementedError(
|
116
|
+
"No event log writer plugins are currently supported."
|
117
|
+
)
|
118
|
+
|
119
|
+
def get_fleet_event_log_writer_plugins() -> dict[str, type[EventLogWriterPlugin]]:
|
120
|
+
"""Return all Fleet API event log writer plugins."""
|
121
|
+
raise NotImplementedError(
|
122
|
+
"No event log writer plugins are currently supported."
|
123
|
+
)
|
124
|
+
|
108
125
|
|
109
126
|
def start_server( # pylint: disable=too-many-arguments,too-many-locals
|
110
127
|
*,
|
@@ -276,9 +293,13 @@ def run_superlink() -> None:
|
|
276
293
|
verify_tls_cert = not getattr(args, "disable_oidc_tls_cert_verification", None)
|
277
294
|
|
278
295
|
auth_plugin: Optional[ExecAuthPlugin] = None
|
296
|
+
event_log_plugin: Optional[EventLogWriterPlugin] = None
|
279
297
|
# Load the auth plugin if the args.user_auth_config is provided
|
280
298
|
if cfg_path := getattr(args, "user_auth_config", None):
|
281
299
|
auth_plugin = _try_obtain_exec_auth_plugin(Path(cfg_path), verify_tls_cert)
|
300
|
+
# Enable event logging if the args.enable_event_log is True
|
301
|
+
if args.enable_event_log:
|
302
|
+
event_log_plugin = _try_obtain_exec_event_log_writer_plugin()
|
282
303
|
|
283
304
|
# Initialize StateFactory
|
284
305
|
state_factory = LinkStateFactory(args.database)
|
@@ -298,6 +319,7 @@ def run_superlink() -> None:
|
|
298
319
|
[args.executor_config] if args.executor_config else args.executor_config
|
299
320
|
),
|
300
321
|
auth_plugin=auth_plugin,
|
322
|
+
event_log_plugin=event_log_plugin,
|
301
323
|
)
|
302
324
|
grpc_servers = [exec_server]
|
303
325
|
|
@@ -389,6 +411,11 @@ def run_superlink() -> None:
|
|
389
411
|
log(DEBUG, "Automatic node authentication enabled")
|
390
412
|
|
391
413
|
interceptors = [AuthenticateServerInterceptor(state_factory, auto_auth)]
|
414
|
+
if getattr(args, "enable_event_log", None):
|
415
|
+
fleet_log_plugin = _try_obtain_fleet_event_log_writer_plugin()
|
416
|
+
if fleet_log_plugin is not None:
|
417
|
+
interceptors.append(FleetEventLogInterceptor(fleet_log_plugin))
|
418
|
+
log(INFO, "Flower Fleet event logging enabled")
|
392
419
|
|
393
420
|
fleet_server = _run_fleet_api_grpc_rere(
|
394
421
|
address=fleet_address,
|
@@ -613,6 +640,34 @@ def _try_obtain_exec_auth_plugin(
|
|
613
640
|
sys.exit("No authentication plugins are currently supported.")
|
614
641
|
|
615
642
|
|
643
|
+
def _try_obtain_exec_event_log_writer_plugin() -> Optional[EventLogWriterPlugin]:
|
644
|
+
"""Return an instance of the event log writer plugin."""
|
645
|
+
try:
|
646
|
+
all_plugins: dict[str, type[EventLogWriterPlugin]] = (
|
647
|
+
get_exec_event_log_writer_plugins()
|
648
|
+
)
|
649
|
+
plugin_class = all_plugins[EventLogWriterType.STDOUT]
|
650
|
+
return plugin_class()
|
651
|
+
except KeyError:
|
652
|
+
sys.exit("No event log writer plugin is provided.")
|
653
|
+
except NotImplementedError:
|
654
|
+
sys.exit("No event log writer plugins are currently supported.")
|
655
|
+
|
656
|
+
|
657
|
+
def _try_obtain_fleet_event_log_writer_plugin() -> Optional[EventLogWriterPlugin]:
|
658
|
+
"""Return an instance of the Fleet Servicer event log writer plugin."""
|
659
|
+
try:
|
660
|
+
all_plugins: dict[str, type[EventLogWriterPlugin]] = (
|
661
|
+
get_fleet_event_log_writer_plugins()
|
662
|
+
)
|
663
|
+
plugin_class = all_plugins[EventLogWriterType.STDOUT]
|
664
|
+
return plugin_class()
|
665
|
+
except KeyError:
|
666
|
+
sys.exit("No Fleet API event log writer plugin is provided.")
|
667
|
+
except NotImplementedError:
|
668
|
+
sys.exit("No Fleet API event log writer plugins are currently supported.")
|
669
|
+
|
670
|
+
|
616
671
|
def _run_fleet_api_grpc_rere(
|
617
672
|
address: str,
|
618
673
|
state_factory: LinkStateFactory,
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# Copyright 2025 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
|
+
"""Flower Fleet API event log interceptor."""
|
16
|
+
|
17
|
+
|
18
|
+
from typing import Any, Callable, cast
|
19
|
+
|
20
|
+
import grpc
|
21
|
+
from google.protobuf.message import Message as GrpcMessage
|
22
|
+
|
23
|
+
from flwr.common.event_log_plugin.event_log_plugin import EventLogWriterPlugin
|
24
|
+
from flwr.common.typing import LogEntry
|
25
|
+
|
26
|
+
|
27
|
+
class FleetEventLogInterceptor(grpc.ServerInterceptor): # type: ignore
|
28
|
+
"""Fleet API interceptor for logging events."""
|
29
|
+
|
30
|
+
def __init__(self, log_plugin: EventLogWriterPlugin) -> None:
|
31
|
+
self.log_plugin = log_plugin
|
32
|
+
|
33
|
+
def intercept_service(
|
34
|
+
self,
|
35
|
+
continuation: Callable[[Any], Any],
|
36
|
+
handler_call_details: grpc.HandlerCallDetails,
|
37
|
+
) -> grpc.RpcMethodHandler:
|
38
|
+
"""Flower Fleet API server interceptor logging logic.
|
39
|
+
|
40
|
+
Intercept all unary-unary calls from users and log the event. Continue RPC call
|
41
|
+
if event logger is enabled on the SuperLink, else, terminate RPC call by setting
|
42
|
+
context to abort.
|
43
|
+
"""
|
44
|
+
# One of the method handlers in
|
45
|
+
# `flwr.server.superlink.fleet.grpc_rere.fleet_servicer.FleetServicer`
|
46
|
+
method_handler: grpc.RpcMethodHandler = continuation(handler_call_details)
|
47
|
+
method_name: str = handler_call_details.method
|
48
|
+
return self._generic_event_log_unary_method_handler(method_handler, method_name)
|
49
|
+
|
50
|
+
def _generic_event_log_unary_method_handler(
|
51
|
+
self, method_handler: grpc.RpcMethodHandler, method_name: str
|
52
|
+
) -> grpc.RpcMethodHandler:
|
53
|
+
def _generic_method_handler(
|
54
|
+
request: GrpcMessage,
|
55
|
+
context: grpc.ServicerContext,
|
56
|
+
) -> GrpcMessage:
|
57
|
+
log_entry: LogEntry
|
58
|
+
# Log before call
|
59
|
+
log_entry = self.log_plugin.compose_log_before_event(
|
60
|
+
request=request,
|
61
|
+
context=context,
|
62
|
+
user_info=None,
|
63
|
+
method_name=method_name,
|
64
|
+
)
|
65
|
+
self.log_plugin.write_log(log_entry)
|
66
|
+
|
67
|
+
call = method_handler.unary_unary
|
68
|
+
unary_response, error = None, None
|
69
|
+
try:
|
70
|
+
unary_response = cast(GrpcMessage, call(request, context))
|
71
|
+
except Exception as e: # pylint: disable=broad-except
|
72
|
+
error = e
|
73
|
+
raise
|
74
|
+
finally:
|
75
|
+
log_entry = self.log_plugin.compose_log_after_event(
|
76
|
+
request=request,
|
77
|
+
context=context,
|
78
|
+
user_info=None,
|
79
|
+
method_name=method_name,
|
80
|
+
response=unary_response or error,
|
81
|
+
)
|
82
|
+
self.log_plugin.write_log(log_entry)
|
83
|
+
return unary_response
|
84
|
+
|
85
|
+
if method_handler.unary_unary:
|
86
|
+
message_handler = grpc.unary_unary_rpc_method_handler
|
87
|
+
else:
|
88
|
+
# If the method type is not `unary_unary` raise an error
|
89
|
+
raise NotImplementedError("This RPC method type is not supported.")
|
90
|
+
return message_handler(
|
91
|
+
_generic_method_handler,
|
92
|
+
request_deserializer=method_handler.request_deserializer,
|
93
|
+
response_serializer=method_handler.response_serializer,
|
94
|
+
)
|
flwr/superexec/exec_grpc.py
CHANGED
@@ -15,7 +15,6 @@
|
|
15
15
|
"""SuperExec gRPC API."""
|
16
16
|
|
17
17
|
|
18
|
-
from collections.abc import Sequence
|
19
18
|
from logging import INFO
|
20
19
|
from typing import Optional
|
21
20
|
|
@@ -23,12 +22,14 @@ import grpc
|
|
23
22
|
|
24
23
|
from flwr.common import GRPC_MAX_MESSAGE_LENGTH
|
25
24
|
from flwr.common.auth_plugin import ExecAuthPlugin
|
25
|
+
from flwr.common.event_log_plugin import EventLogWriterPlugin
|
26
26
|
from flwr.common.grpc import generic_create_grpc_server
|
27
27
|
from flwr.common.logger import log
|
28
28
|
from flwr.common.typing import UserConfig
|
29
29
|
from flwr.proto.exec_pb2_grpc import add_ExecServicer_to_server
|
30
30
|
from flwr.server.superlink.ffs.ffs_factory import FfsFactory
|
31
31
|
from flwr.server.superlink.linkstate import LinkStateFactory
|
32
|
+
from flwr.superexec.exec_event_log_interceptor import ExecEventLogInterceptor
|
32
33
|
from flwr.superexec.exec_user_auth_interceptor import ExecUserAuthInterceptor
|
33
34
|
|
34
35
|
from .exec_servicer import ExecServicer
|
@@ -44,6 +45,7 @@ def run_exec_api_grpc(
|
|
44
45
|
certificates: Optional[tuple[bytes, bytes, bytes]],
|
45
46
|
config: UserConfig,
|
46
47
|
auth_plugin: Optional[ExecAuthPlugin] = None,
|
48
|
+
event_log_plugin: Optional[EventLogWriterPlugin] = None,
|
47
49
|
) -> grpc.Server:
|
48
50
|
"""Run Exec API (gRPC, request-response)."""
|
49
51
|
executor.set_config(config)
|
@@ -54,16 +56,20 @@ def run_exec_api_grpc(
|
|
54
56
|
executor=executor,
|
55
57
|
auth_plugin=auth_plugin,
|
56
58
|
)
|
57
|
-
interceptors:
|
59
|
+
interceptors: list[grpc.ServerInterceptor] = []
|
58
60
|
if auth_plugin is not None:
|
59
|
-
interceptors
|
61
|
+
interceptors.append(ExecUserAuthInterceptor(auth_plugin))
|
62
|
+
# Event log interceptor must be added after user auth interceptor
|
63
|
+
if event_log_plugin is not None:
|
64
|
+
interceptors.append(ExecEventLogInterceptor(event_log_plugin))
|
65
|
+
log(INFO, "Flower event logging enabled")
|
60
66
|
exec_add_servicer_to_server_fn = add_ExecServicer_to_server
|
61
67
|
exec_grpc_server = generic_create_grpc_server(
|
62
68
|
servicer_and_add_fn=(exec_servicer, exec_add_servicer_to_server_fn),
|
63
69
|
server_address=address,
|
64
70
|
max_message_length=GRPC_MAX_MESSAGE_LENGTH,
|
65
71
|
certificates=certificates,
|
66
|
-
interceptors=interceptors,
|
72
|
+
interceptors=interceptors or None,
|
67
73
|
)
|
68
74
|
|
69
75
|
if auth_plugin is None:
|
{flwr_nightly-1.17.0.dev20250312.dist-info → flwr_nightly-1.17.0.dev20250313.dist-info}/RECORD
RENAMED
@@ -116,14 +116,14 @@ flwr/common/args.py,sha256=2gGT2a3SPJ0-LTNKnhBsZ-ESIoW9FGpw-9xkUSs8qwk,5417
|
|
116
116
|
flwr/common/auth_plugin/__init__.py,sha256=1Y8Oj3iB49IHDu9tvDih1J74Ygu7k85V9s2A4WORPyA,887
|
117
117
|
flwr/common/auth_plugin/auth_plugin.py,sha256=dQU5U4uJIA5XqgOJ3PankHWq-uXCaMvO74khaMPGdiU,3938
|
118
118
|
flwr/common/config.py,sha256=SAkG3BztnA6iupXxF3GAIpGmWVVCH0ptyMpC9yjr_14,13965
|
119
|
-
flwr/common/constant.py,sha256=
|
119
|
+
flwr/common/constant.py,sha256=lAnqe63ZzW0NcS306rnEVICpJSXCFNoPj4L1X-p0FCA,6853
|
120
120
|
flwr/common/context.py,sha256=uJ-mnoC_8y_udEb3kAX-r8CPphNTWM72z1AlsvQEu54,2403
|
121
121
|
flwr/common/date.py,sha256=NHHpESce5wYqEwoDXf09gp9U9l_5Bmlh2BsOcwS-kDM,1554
|
122
122
|
flwr/common/differential_privacy.py,sha256=YA01NqjddKNAEVmf7hXmOVxOjhekgzvJudk3mBGq-2k,6148
|
123
123
|
flwr/common/differential_privacy_constants.py,sha256=c7b7tqgvT7yMK0XN9ndiTBs4mQf6d3qk6K7KBZGlV4Q,1074
|
124
124
|
flwr/common/dp.py,sha256=vddkvyjV2FhRoN4VuU2LeAM1UBn7dQB8_W-Qdiveal8,1978
|
125
125
|
flwr/common/event_log_plugin/__init__.py,sha256=ts3VAL3Fk6Grp1EK_1Qg_V-BfOof9F86iBx4rbrEkyo,838
|
126
|
-
flwr/common/event_log_plugin/event_log_plugin.py,sha256=
|
126
|
+
flwr/common/event_log_plugin/event_log_plugin.py,sha256=aGRc_MKHIjxkAP5nYf9wXWpcU-DNhwUH-qzhZG8MRIQ,2042
|
127
127
|
flwr/common/exit/__init__.py,sha256=-ZOJYLaNnR729a7VzZiFsLiqngzKQh3xc27svYStZ_Q,826
|
128
128
|
flwr/common/exit/exit.py,sha256=DmZFyksp-w1sFDQekq5Z-qfnr-ivCAv78aQkqj-TDps,3458
|
129
129
|
flwr/common/exit/exit_code.py,sha256=PNEnCrZfOILjfDAFu5m-2YWEJBrk97xglq4zCUlqV7E,3470
|
@@ -214,7 +214,7 @@ flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPc
|
|
214
214
|
flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
|
215
215
|
flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
216
216
|
flwr/server/__init__.py,sha256=cEg1oecBu4cKB69iJCqWEylC8b5XW47bl7rQiJsdTvM,1528
|
217
|
-
flwr/server/app.py,sha256=
|
217
|
+
flwr/server/app.py,sha256=yCfZSKCSu2w7jJYIj-dpF0inyPpsY-KkjgVcmMVcZiY,33614
|
218
218
|
flwr/server/client_manager.py,sha256=7Ese0tgrH-i-ms363feYZJKwB8gWnXSmg_hYF2Bju4U,6227
|
219
219
|
flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
|
220
220
|
flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
|
@@ -227,6 +227,7 @@ flwr/server/driver/__init__.py,sha256=bikRv6CjTwSvYh7tf10gziU5o2YotOWhhftz2tr3KD
|
|
227
227
|
flwr/server/driver/driver.py,sha256=X072eFWl8Kx-aZbahTkpAc1wwoojr8A4uO2yozwwSbE,5705
|
228
228
|
flwr/server/driver/grpc_driver.py,sha256=u3kj9Ej5vErlRcdeF_8giqVXWLP0obT405Kjv6vC-Vw,10298
|
229
229
|
flwr/server/driver/inmemory_driver.py,sha256=p6p9RykDfoty94izzD4i11Xp7A8t1KUaHpbKbbVZAdU,6407
|
230
|
+
flwr/server/fleet_event_log_interceptor.py,sha256=IIZFv4tAudDpLsRTkU5DWVEQVUZupKRBZl-ktK0b6UU,3802
|
230
231
|
flwr/server/history.py,sha256=qSb5_pPTrwofpSYGsZWzMPkl_4uJ4mJFWesxXDrEvDU,5026
|
231
232
|
flwr/server/run_serverapp.py,sha256=tyAYB5UEiUd63VG4XiYBUUiivh77SpIol1cGS4xtYdk,2077
|
232
233
|
flwr/server/server.py,sha256=1ZsFEptmAV-L2vP2etNC9Ed5CLSxpuKzUFkAPQ4l5Xc,17893
|
@@ -320,13 +321,13 @@ flwr/superexec/__init__.py,sha256=fcj366jh4RFby_vDwLroU4kepzqbnJgseZD_jUr_Mko,71
|
|
320
321
|
flwr/superexec/app.py,sha256=C0T2LMjuyF__I5V1FKfjtWtbsQPxK_EgL4vuhWIwG8s,1465
|
321
322
|
flwr/superexec/deployment.py,sha256=wZ9G42gGS91knfplswh95MnQ83Fzu-rs6wcuNgDmmvY,6735
|
322
323
|
flwr/superexec/exec_event_log_interceptor.py,sha256=zFu1MQu3XkWa9PUTQgt5wb3BL_eR2dFS5M3BR5hbX34,5805
|
323
|
-
flwr/superexec/exec_grpc.py,sha256=
|
324
|
+
flwr/superexec/exec_grpc.py,sha256=9-WF6qPuhiYohMe3SIZ5Sapp_dLjICvm5QfdTNizsJg,3252
|
324
325
|
flwr/superexec/exec_servicer.py,sha256=4UpzJqPUHkBG2PZNe2lrX7XFVDOL6yw_HcoBHxuXE9A,8349
|
325
326
|
flwr/superexec/exec_user_auth_interceptor.py,sha256=2kXjjJcrZyff893QTFLQD6zxC4pdVwtN4Rc66jHptfE,4440
|
326
327
|
flwr/superexec/executor.py,sha256=_B55WW2TD1fBINpabSSDRenVHXYmvlfhv-k8hJKU4lQ,3115
|
327
328
|
flwr/superexec/simulation.py,sha256=WQDon15oqpMopAZnwRZoTICYCfHqtkvFSqiTQ2hLD_g,4088
|
328
|
-
flwr_nightly-1.17.0.
|
329
|
-
flwr_nightly-1.17.0.
|
330
|
-
flwr_nightly-1.17.0.
|
331
|
-
flwr_nightly-1.17.0.
|
332
|
-
flwr_nightly-1.17.0.
|
329
|
+
flwr_nightly-1.17.0.dev20250313.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
330
|
+
flwr_nightly-1.17.0.dev20250313.dist-info/METADATA,sha256=iAYJEWp0Rxernl7OApLQ2wsxqmysOtJ0UJ7qpO3wv9Y,15877
|
331
|
+
flwr_nightly-1.17.0.dev20250313.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
332
|
+
flwr_nightly-1.17.0.dev20250313.dist-info/entry_points.txt,sha256=2-1L-GNKhwGw2_7_RoH55vHw2SIHjdAQy3HAVAWl9PY,374
|
333
|
+
flwr_nightly-1.17.0.dev20250313.dist-info/RECORD,,
|
{flwr_nightly-1.17.0.dev20250312.dist-info → flwr_nightly-1.17.0.dev20250313.dist-info}/LICENSE
RENAMED
File without changes
|
{flwr_nightly-1.17.0.dev20250312.dist-info → flwr_nightly-1.17.0.dev20250313.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|