flwr-nightly 1.17.0.dev20250314__py3-none-any.whl → 1.17.0.dev20250316__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/client/client_app.py +161 -94
- flwr/common/constant.py +1 -0
- flwr/common/message.py +58 -1
- flwr/server/superlink/linkstate/utils.py +8 -2
- {flwr_nightly-1.17.0.dev20250314.dist-info → flwr_nightly-1.17.0.dev20250316.dist-info}/METADATA +1 -1
- {flwr_nightly-1.17.0.dev20250314.dist-info → flwr_nightly-1.17.0.dev20250316.dist-info}/RECORD +9 -9
- {flwr_nightly-1.17.0.dev20250314.dist-info → flwr_nightly-1.17.0.dev20250316.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.17.0.dev20250314.dist-info → flwr_nightly-1.17.0.dev20250316.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.17.0.dev20250314.dist-info → flwr_nightly-1.17.0.dev20250316.dist-info}/entry_points.txt +0 -0
flwr/client/client_app.py
CHANGED
@@ -28,9 +28,12 @@ from flwr.client.mod.utils import make_ffn
|
|
28
28
|
from flwr.client.typing import ClientFnExt, Mod
|
29
29
|
from flwr.common import Context, Message, MessageType
|
30
30
|
from flwr.common.logger import warn_deprecated_feature, warn_preview_feature
|
31
|
+
from flwr.common.message import validate_message_type
|
31
32
|
|
32
33
|
from .typing import ClientAppCallable
|
33
34
|
|
35
|
+
DEFAULT_ACTION = "default"
|
36
|
+
|
34
37
|
|
35
38
|
def _alert_erroneous_client_fn() -> None:
|
36
39
|
raise ValueError(
|
@@ -110,6 +113,7 @@ class ClientApp:
|
|
110
113
|
mods: Optional[list[Mod]] = None,
|
111
114
|
) -> None:
|
112
115
|
self._mods: list[Mod] = mods if mods is not None else []
|
116
|
+
self._registered_funcs: dict[str, ClientAppCallable] = {}
|
113
117
|
|
114
118
|
# Create wrapper function for `handle`
|
115
119
|
self._call: Optional[ClientAppCallable] = None
|
@@ -129,10 +133,7 @@ class ClientApp:
|
|
129
133
|
# Wrap mods around the wrapped handle function
|
130
134
|
self._call = make_ffn(ffn, mods if mods is not None else [])
|
131
135
|
|
132
|
-
#
|
133
|
-
self._train: Optional[ClientAppCallable] = None
|
134
|
-
self._evaluate: Optional[ClientAppCallable] = None
|
135
|
-
self._query: Optional[ClientAppCallable] = None
|
136
|
+
# Lifespan function
|
136
137
|
self._lifespan = _empty_lifespan
|
137
138
|
|
138
139
|
def __call__(self, message: Message, context: Context) -> Message:
|
@@ -142,27 +143,41 @@ class ClientApp:
|
|
142
143
|
if self._call:
|
143
144
|
return self._call(message, context)
|
144
145
|
|
145
|
-
#
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
146
|
+
# Get the category and the action
|
147
|
+
# A valid message type is of the form "<category>" or "<category>.<action>",
|
148
|
+
# where <category> must be "train"/"evaluate"/"query", and <action> is a
|
149
|
+
# valid Python identifier
|
150
|
+
if not validate_message_type(message.metadata.message_type):
|
151
|
+
raise ValueError(
|
152
|
+
f"Invalid message type: {message.metadata.message_type}"
|
153
|
+
)
|
154
|
+
|
155
|
+
category, action = message.metadata.message_type, DEFAULT_ACTION
|
156
|
+
if "." in category:
|
157
|
+
category, action = category.split(".")
|
158
|
+
|
159
|
+
# Check if the function is registered
|
160
|
+
if (full_name := f"{category}.{action}") in self._registered_funcs:
|
161
|
+
return self._registered_funcs[full_name](message, context)
|
162
|
+
|
163
|
+
raise ValueError(f"No {category} function registered with name '{action}'")
|
161
164
|
|
162
165
|
def train(
|
163
|
-
self, mods: Optional[list[Mod]] = None
|
166
|
+
self, action: str = DEFAULT_ACTION, *, mods: Optional[list[Mod]] = None
|
164
167
|
) -> Callable[[ClientAppCallable], ClientAppCallable]:
|
165
|
-
"""
|
168
|
+
"""Register a train function with the ``ClientApp``.
|
169
|
+
|
170
|
+
Parameters
|
171
|
+
----------
|
172
|
+
action : str (default: "default")
|
173
|
+
The action name used to route messages. Defaults to "default".
|
174
|
+
mods : Optional[list[Mod]] (default: None)
|
175
|
+
A list of function-specific modifiers.
|
176
|
+
|
177
|
+
Returns
|
178
|
+
-------
|
179
|
+
Callable[[ClientAppCallable], ClientAppCallable]
|
180
|
+
A decorator that registers a train function with the ``ClientApp``.
|
166
181
|
|
167
182
|
Examples
|
168
183
|
--------
|
@@ -172,42 +187,52 @@ class ClientApp:
|
|
172
187
|
>>>
|
173
188
|
>>> @app.train()
|
174
189
|
>>> def train(message: Message, context: Context) -> Message:
|
175
|
-
>>>
|
176
|
-
>>>
|
177
|
-
>>>
|
190
|
+
>>> print("Executing default train function")
|
191
|
+
>>> # Create and return an echo reply message
|
192
|
+
>>> return message.create_reply(content=message.content)
|
193
|
+
|
194
|
+
Registering a train function with a custom action name:
|
178
195
|
|
179
|
-
|
196
|
+
>>> app = ClientApp()
|
197
|
+
>>>
|
198
|
+
>>> # Messages with `message_type="train.custom_action"` will be
|
199
|
+
>>> # routed to this function.
|
200
|
+
>>> @app.train("custom_action")
|
201
|
+
>>> def custom_action(message: Message, context: Context) -> Message:
|
202
|
+
>>> print("Executing train function for custom action")
|
203
|
+
>>> return message.create_reply(content=message.content)
|
204
|
+
|
205
|
+
Registering a train function with a function-specific Flower Mod:
|
180
206
|
|
181
207
|
>>> from flwr.client.mod import message_size_mod
|
182
208
|
>>>
|
183
209
|
>>> app = ClientApp()
|
184
210
|
>>>
|
211
|
+
>>> # Using the `mods` argument to apply a function-specific mod.
|
185
212
|
>>> @app.train(mods=[message_size_mod])
|
186
213
|
>>> def train(message: Message, context: Context) -> Message:
|
187
|
-
>>>
|
188
|
-
>>>
|
214
|
+
>>> print("Executing train function with message size mod")
|
215
|
+
>>> # Create and return an echo reply message
|
216
|
+
>>> return message.create_reply(content=message.content)
|
189
217
|
"""
|
190
|
-
|
191
|
-
def train_decorator(train_fn: ClientAppCallable) -> ClientAppCallable:
|
192
|
-
"""Register the train fn with the ServerApp object."""
|
193
|
-
if self._call:
|
194
|
-
raise _registration_error(MessageType.TRAIN)
|
195
|
-
|
196
|
-
warn_preview_feature("ClientApp-register-train-function")
|
197
|
-
|
198
|
-
# Register provided function with the ClientApp object
|
199
|
-
# Wrap mods around the wrapped step function
|
200
|
-
self._train = make_ffn(train_fn, self._mods + (mods or []))
|
201
|
-
|
202
|
-
# Return provided function unmodified
|
203
|
-
return train_fn
|
204
|
-
|
205
|
-
return train_decorator
|
218
|
+
return _get_decorator(self, MessageType.TRAIN, action, mods)
|
206
219
|
|
207
220
|
def evaluate(
|
208
|
-
self, mods: Optional[list[Mod]] = None
|
221
|
+
self, action: str = DEFAULT_ACTION, *, mods: Optional[list[Mod]] = None
|
209
222
|
) -> Callable[[ClientAppCallable], ClientAppCallable]:
|
210
|
-
"""
|
223
|
+
"""Register an evaluate function with the ``ClientApp``.
|
224
|
+
|
225
|
+
Parameters
|
226
|
+
----------
|
227
|
+
action : str (default: "default")
|
228
|
+
The action name used to route messages. Defaults to "default".
|
229
|
+
mods : Optional[list[Mod]] (default: None)
|
230
|
+
A list of function-specific modifiers.
|
231
|
+
|
232
|
+
Returns
|
233
|
+
-------
|
234
|
+
Callable[[ClientAppCallable], ClientAppCallable]
|
235
|
+
A decorator that registers an evaluate function with the ``ClientApp``.
|
211
236
|
|
212
237
|
Examples
|
213
238
|
--------
|
@@ -217,43 +242,52 @@ class ClientApp:
|
|
217
242
|
>>>
|
218
243
|
>>> @app.evaluate()
|
219
244
|
>>> def evaluate(message: Message, context: Context) -> Message:
|
220
|
-
>>>
|
221
|
-
>>>
|
222
|
-
>>>
|
245
|
+
>>> print("Executing default evaluate function")
|
246
|
+
>>> # Create and return an echo reply message
|
247
|
+
>>> return message.create_reply(content=message.content)
|
248
|
+
|
249
|
+
Registering an evaluate function with a custom action name:
|
250
|
+
|
251
|
+
>>> app = ClientApp()
|
252
|
+
>>>
|
253
|
+
>>> # Messages with `message_type="evaluate.custom_action"` will be
|
254
|
+
>>> # routed to this function.
|
255
|
+
>>> @app.evaluate("custom_action")
|
256
|
+
>>> def custom_action(message: Message, context: Context) -> Message:
|
257
|
+
>>> print("Executing evaluate function for custom action")
|
258
|
+
>>> return message.create_reply(content=message.content)
|
223
259
|
|
224
|
-
Registering an evaluate function with a function-specific
|
260
|
+
Registering an evaluate function with a function-specific Flower Mod:
|
225
261
|
|
226
262
|
>>> from flwr.client.mod import message_size_mod
|
227
263
|
>>>
|
228
264
|
>>> app = ClientApp()
|
229
265
|
>>>
|
266
|
+
>>> # Using the `mods` argument to apply a function-specific mod.
|
230
267
|
>>> @app.evaluate(mods=[message_size_mod])
|
231
268
|
>>> def evaluate(message: Message, context: Context) -> Message:
|
232
|
-
>>>
|
233
|
-
>>>
|
234
|
-
>>>
|
269
|
+
>>> print("Executing evaluate function with message size mod")
|
270
|
+
>>> # Create and return an echo reply message
|
271
|
+
>>> return message.create_reply(content=message.content)
|
235
272
|
"""
|
236
|
-
|
237
|
-
def evaluate_decorator(evaluate_fn: ClientAppCallable) -> ClientAppCallable:
|
238
|
-
"""Register the evaluate fn with the ServerApp object."""
|
239
|
-
if self._call:
|
240
|
-
raise _registration_error(MessageType.EVALUATE)
|
241
|
-
|
242
|
-
warn_preview_feature("ClientApp-register-evaluate-function")
|
243
|
-
|
244
|
-
# Register provided function with the ClientApp object
|
245
|
-
# Wrap mods around the wrapped step function
|
246
|
-
self._evaluate = make_ffn(evaluate_fn, self._mods + (mods or []))
|
247
|
-
|
248
|
-
# Return provided function unmodified
|
249
|
-
return evaluate_fn
|
250
|
-
|
251
|
-
return evaluate_decorator
|
273
|
+
return _get_decorator(self, MessageType.EVALUATE, action, mods)
|
252
274
|
|
253
275
|
def query(
|
254
|
-
self, mods: Optional[list[Mod]] = None
|
276
|
+
self, action: str = DEFAULT_ACTION, *, mods: Optional[list[Mod]] = None
|
255
277
|
) -> Callable[[ClientAppCallable], ClientAppCallable]:
|
256
|
-
"""
|
278
|
+
"""Register a query function with the ``ClientApp``.
|
279
|
+
|
280
|
+
Parameters
|
281
|
+
----------
|
282
|
+
action : str (default: "default")
|
283
|
+
The action name used to route messages. Defaults to "default".
|
284
|
+
mods : Optional[list[Mod]] (default: None)
|
285
|
+
A list of function-specific modifiers.
|
286
|
+
|
287
|
+
Returns
|
288
|
+
-------
|
289
|
+
Callable[[ClientAppCallable], ClientAppCallable]
|
290
|
+
A decorator that registers a query function with the ``ClientApp``.
|
257
291
|
|
258
292
|
Examples
|
259
293
|
--------
|
@@ -263,38 +297,35 @@ class ClientApp:
|
|
263
297
|
>>>
|
264
298
|
>>> @app.query()
|
265
299
|
>>> def query(message: Message, context: Context) -> Message:
|
266
|
-
>>>
|
267
|
-
>>>
|
268
|
-
>>>
|
300
|
+
>>> print("Executing default query function")
|
301
|
+
>>> # Create and return an echo reply message
|
302
|
+
>>> return message.create_reply(content=message.content)
|
269
303
|
|
270
|
-
Registering a query function with a
|
304
|
+
Registering a query function with a custom action name:
|
305
|
+
|
306
|
+
>>> app = ClientApp()
|
307
|
+
>>>
|
308
|
+
>>> # Messages with `message_type="query.custom_action"` will be
|
309
|
+
>>> # routed to this function.
|
310
|
+
>>> @app.query("custom_action")
|
311
|
+
>>> def custom_action(message: Message, context: Context) -> Message:
|
312
|
+
>>> print("Executing query function for custom action")
|
313
|
+
>>> return message.create_reply(content=message.content)
|
314
|
+
|
315
|
+
Registering a query function with a function-specific Flower Mod:
|
271
316
|
|
272
317
|
>>> from flwr.client.mod import message_size_mod
|
273
318
|
>>>
|
274
319
|
>>> app = ClientApp()
|
275
320
|
>>>
|
321
|
+
>>> # Using the `mods` argument to apply a function-specific mod.
|
276
322
|
>>> @app.query(mods=[message_size_mod])
|
277
323
|
>>> def query(message: Message, context: Context) -> Message:
|
278
|
-
>>>
|
279
|
-
>>>
|
280
|
-
>>>
|
324
|
+
>>> print("Executing query function with message size mod")
|
325
|
+
>>> # Create and return an echo reply message
|
326
|
+
>>> return message.create_reply(content=message.content)
|
281
327
|
"""
|
282
|
-
|
283
|
-
def query_decorator(query_fn: ClientAppCallable) -> ClientAppCallable:
|
284
|
-
"""Register the query fn with the ServerApp object."""
|
285
|
-
if self._call:
|
286
|
-
raise _registration_error(MessageType.QUERY)
|
287
|
-
|
288
|
-
warn_preview_feature("ClientApp-register-query-function")
|
289
|
-
|
290
|
-
# Register provided function with the ClientApp object
|
291
|
-
# Wrap mods around the wrapped step function
|
292
|
-
self._query = make_ffn(query_fn, self._mods + (mods or []))
|
293
|
-
|
294
|
-
# Return provided function unmodified
|
295
|
-
return query_fn
|
296
|
-
|
297
|
-
return query_decorator
|
328
|
+
return _get_decorator(self, MessageType.QUERY, action, mods)
|
298
329
|
|
299
330
|
def lifespan(
|
300
331
|
self,
|
@@ -365,6 +396,42 @@ class LoadClientAppError(Exception):
|
|
365
396
|
"""Error when trying to load `ClientApp`."""
|
366
397
|
|
367
398
|
|
399
|
+
def _get_decorator(
|
400
|
+
app: ClientApp, category: str, action: str, mods: Optional[list[Mod]]
|
401
|
+
) -> Callable[[ClientAppCallable], ClientAppCallable]:
|
402
|
+
"""Get the decorator for the given category and action."""
|
403
|
+
# pylint: disable=protected-access
|
404
|
+
if app._call:
|
405
|
+
raise _registration_error(category)
|
406
|
+
|
407
|
+
def decorator(fn: ClientAppCallable) -> ClientAppCallable:
|
408
|
+
warn_preview_feature(f"ClientApp-register-{category}-function")
|
409
|
+
|
410
|
+
# Check if the name is a valid Python identifier
|
411
|
+
if not action.isidentifier():
|
412
|
+
raise ValueError(
|
413
|
+
f"Cannot register {category} function with name '{action}'. "
|
414
|
+
"The name must follow Python's function naming rules."
|
415
|
+
)
|
416
|
+
|
417
|
+
# Check if the name is already registered
|
418
|
+
full_name = f"{category}.{action}" # Full name of the message type
|
419
|
+
if full_name in app._registered_funcs:
|
420
|
+
raise ValueError(
|
421
|
+
f"Cannot register {category} function with name '{action}'. "
|
422
|
+
f"A {category} function with the name '{action}' is already registered."
|
423
|
+
)
|
424
|
+
|
425
|
+
# Register provided function with the ClientApp object
|
426
|
+
app._registered_funcs[full_name] = make_ffn(fn, app._mods + (mods or []))
|
427
|
+
|
428
|
+
# Return provided function unmodified
|
429
|
+
return fn
|
430
|
+
|
431
|
+
# pylint: enable=protected-access
|
432
|
+
return decorator
|
433
|
+
|
434
|
+
|
368
435
|
def _registration_error(fn_name: str) -> ValueError:
|
369
436
|
return ValueError(
|
370
437
|
f"""Use either `@app.{fn_name}()` or `client_fn`, but not both.
|
flwr/common/constant.py
CHANGED
flwr/common/message.py
CHANGED
@@ -21,7 +21,7 @@ import time
|
|
21
21
|
from logging import WARNING
|
22
22
|
from typing import Optional, cast
|
23
23
|
|
24
|
-
from .constant import MESSAGE_TTL_TOLERANCE
|
24
|
+
from .constant import MESSAGE_TTL_TOLERANCE, MessageType, MessageTypeLegacy
|
25
25
|
from .logger import log
|
26
26
|
from .record import RecordSet
|
27
27
|
|
@@ -75,6 +75,7 @@ class Metadata: # pylint: disable=too-many-instance-attributes
|
|
75
75
|
"_message_type": message_type,
|
76
76
|
}
|
77
77
|
self.__dict__.update(var_dict)
|
78
|
+
self.message_type = message_type # Trigger validation
|
78
79
|
|
79
80
|
@property
|
80
81
|
def run_id(self) -> int:
|
@@ -154,6 +155,17 @@ class Metadata: # pylint: disable=too-many-instance-attributes
|
|
154
155
|
@message_type.setter
|
155
156
|
def message_type(self, value: str) -> None:
|
156
157
|
"""Set message_type."""
|
158
|
+
# Validate message type
|
159
|
+
if validate_legacy_message_type(value):
|
160
|
+
pass # Backward compatibility for legacy message types
|
161
|
+
elif not validate_message_type(value):
|
162
|
+
raise ValueError(
|
163
|
+
f"Invalid message type: '{value}'. "
|
164
|
+
"Expected format: '<category>' or '<category>.<action>', "
|
165
|
+
"where <category> must be 'train', 'evaluate', or 'query', "
|
166
|
+
"and <action> must be a valid Python identifier."
|
167
|
+
)
|
168
|
+
|
157
169
|
self.__dict__["_message_type"] = value
|
158
170
|
|
159
171
|
def __repr__(self) -> str:
|
@@ -417,3 +429,48 @@ def _create_reply_metadata(msg: Message, ttl: float) -> Metadata:
|
|
417
429
|
ttl=ttl,
|
418
430
|
message_type=msg.metadata.message_type,
|
419
431
|
)
|
432
|
+
|
433
|
+
|
434
|
+
def validate_message_type(message_type: str) -> bool:
|
435
|
+
"""Validate if the message type is valid.
|
436
|
+
|
437
|
+
A valid message type format must be one of the following:
|
438
|
+
|
439
|
+
- "<category>"
|
440
|
+
- "<category>.<action>"
|
441
|
+
|
442
|
+
where `category` must be one of "train", "evaluate", or "query",
|
443
|
+
and `action` must be a valid Python identifier.
|
444
|
+
"""
|
445
|
+
# Check if conforming to the format "<category>"
|
446
|
+
valid_types = {
|
447
|
+
MessageType.TRAIN,
|
448
|
+
MessageType.EVALUATE,
|
449
|
+
MessageType.QUERY,
|
450
|
+
MessageType.SYSTEM,
|
451
|
+
}
|
452
|
+
if message_type in valid_types:
|
453
|
+
return True
|
454
|
+
|
455
|
+
# Check if conforming to the format "<category>.<action>"
|
456
|
+
if message_type.count(".") != 1:
|
457
|
+
return False
|
458
|
+
|
459
|
+
category, action = message_type.split(".")
|
460
|
+
if category in valid_types and action.isidentifier():
|
461
|
+
return True
|
462
|
+
|
463
|
+
return False
|
464
|
+
|
465
|
+
|
466
|
+
def validate_legacy_message_type(message_type: str) -> bool:
|
467
|
+
"""Validate if the legacy message type is valid."""
|
468
|
+
# Backward compatibility for legacy message types
|
469
|
+
if message_type in (
|
470
|
+
MessageTypeLegacy.GET_PARAMETERS,
|
471
|
+
MessageTypeLegacy.GET_PROPERTIES,
|
472
|
+
"reconnect",
|
473
|
+
):
|
474
|
+
return True
|
475
|
+
|
476
|
+
return False
|
@@ -20,7 +20,13 @@ from typing import Optional
|
|
20
20
|
from uuid import UUID, uuid4
|
21
21
|
|
22
22
|
from flwr.common import ConfigsRecord, Context, Error, Message, Metadata, now, serde
|
23
|
-
from flwr.common.constant import
|
23
|
+
from flwr.common.constant import (
|
24
|
+
SUPERLINK_NODE_ID,
|
25
|
+
ErrorCode,
|
26
|
+
MessageType,
|
27
|
+
Status,
|
28
|
+
SubStatus,
|
29
|
+
)
|
24
30
|
from flwr.common.typing import RunStatus
|
25
31
|
|
26
32
|
# pylint: disable=E0611
|
@@ -266,7 +272,7 @@ def create_message_error_unavailable_ins_message(reply_to_message: UUID) -> Mess
|
|
266
272
|
dst_node_id=SUPERLINK_NODE_ID,
|
267
273
|
reply_to_message=str(reply_to_message),
|
268
274
|
group_id="", # Unknown
|
269
|
-
message_type=
|
275
|
+
message_type=MessageType.SYSTEM,
|
270
276
|
ttl=0,
|
271
277
|
)
|
272
278
|
|
{flwr_nightly-1.17.0.dev20250314.dist-info → flwr_nightly-1.17.0.dev20250316.dist-info}/RECORD
RENAMED
@@ -74,7 +74,7 @@ flwr/cli/utils.py,sha256=D9XcpxzwkGPNdwX16o0kI-sYnRDMlWYyKNIpz6npRhQ,11236
|
|
74
74
|
flwr/client/__init__.py,sha256=DGDoO0AEAfz-0CUFmLdyUUweAS64-07AOnmDfWUefK4,1192
|
75
75
|
flwr/client/app.py,sha256=tNnef5wGVfqMiiGiWzAuULyy1QpvCKukiRmNi_a2cQc,34261
|
76
76
|
flwr/client/client.py,sha256=8o58nd9o6ZFcMIaVYPGcV4MSjBG4H0oFgWiv8ZEO3oA,7895
|
77
|
-
flwr/client/client_app.py,sha256=
|
77
|
+
flwr/client/client_app.py,sha256=8PpAlN7KT8oNFBFVWbGGi39Zw-fhKBZYLGAs4s1aMdY,17312
|
78
78
|
flwr/client/clientapp/__init__.py,sha256=kZqChGnTChQ1WGSUkIlW2S5bc0d0mzDubCAmZUGRpEY,800
|
79
79
|
flwr/client/clientapp/app.py,sha256=B3GrIMP8BMvltYf4n4xbtlRR1jEPT5-F93KnBCPuPJM,9069
|
80
80
|
flwr/client/clientapp/clientappio_servicer.py,sha256=5L6bjw_j3Mnx9kRFwYwxDNABKurBO5q1jZOWE_X11wQ,8522
|
@@ -116,7 +116,7 @@ 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=2AHf9ujmfkf9YerhtqBe8hAW6iMDJTmnKnyYdlEXEM0,6875
|
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
|
@@ -130,7 +130,7 @@ flwr/common/exit/exit_code.py,sha256=PNEnCrZfOILjfDAFu5m-2YWEJBrk97xglq4zCUlqV7E
|
|
130
130
|
flwr/common/exit_handlers.py,sha256=yclujry30954o0lI7vtknTajskPCvK8TXw2V3RdldXU,3174
|
131
131
|
flwr/common/grpc.py,sha256=7sHNP34LcNZv7J1GewJxXh509XTEbYvoHvXL5tQ3tcw,9798
|
132
132
|
flwr/common/logger.py,sha256=Hund1C6bEhMw3GemlzuFK22tXZ27YeHLrFB0b4LP5f8,13041
|
133
|
-
flwr/common/message.py,sha256=
|
133
|
+
flwr/common/message.py,sha256=dbaIKvw1hJZrLpipbdX6hUw1nhzrxDMXCS7EADQUwE8,16060
|
134
134
|
flwr/common/object_ref.py,sha256=DXL8NtbN17DSYaR-Zc8WYhaG8rv0_D_cclvP7Sa66So,9134
|
135
135
|
flwr/common/parameter.py,sha256=-bFAUayToYDF50FZGrBC1hQYJCQDtB2bbr3ZuVLMtdE,2095
|
136
136
|
flwr/common/pyproject.py,sha256=vEAxl800XiJ1JNJDui8vuVV-08msnB6hLt7o95viZl0,1386
|
@@ -293,7 +293,7 @@ flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=Ss64nq7MgbHwx4LOER
|
|
293
293
|
flwr/server/superlink/linkstate/linkstate.py,sha256=YB3SryGNvt-bE-unYjoloJt9d3xAUPBNLK4mor8gk3M,11851
|
294
294
|
flwr/server/superlink/linkstate/linkstate_factory.py,sha256=ISSMjDlwuN7swxjOeYlTNpI_kuZ8PGkMcJnf1dbhUSE,2069
|
295
295
|
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=Wsx5gD6WRIMLlKarvVV1_dlS7jmfno-yTVW1-rgcIto,38276
|
296
|
-
flwr/server/superlink/linkstate/utils.py,sha256=
|
296
|
+
flwr/server/superlink/linkstate/utils.py,sha256=b26MJdMQyt83EDnhB7FAiq8BFttV_qNHF_E_3d3oBlA,12739
|
297
297
|
flwr/server/superlink/simulation/__init__.py,sha256=mg-oapC9dkzEfjXPQFior5lpWj4g9kwbLovptyYM_g0,718
|
298
298
|
flwr/server/superlink/simulation/simulationio_grpc.py,sha256=8aUrZZLdvprKUfLLqFID4aItus9beU6m1qLQYIPB7k0,2224
|
299
299
|
flwr/server/superlink/simulation/simulationio_servicer.py,sha256=J_TmdqM-Bxgp-iPEI3tvCuBpykw1UX0FouMQalEYAF4,6907
|
@@ -326,8 +326,8 @@ flwr/superexec/exec_servicer.py,sha256=4UpzJqPUHkBG2PZNe2lrX7XFVDOL6yw_HcoBHxuXE
|
|
326
326
|
flwr/superexec/exec_user_auth_interceptor.py,sha256=2kXjjJcrZyff893QTFLQD6zxC4pdVwtN4Rc66jHptfE,4440
|
327
327
|
flwr/superexec/executor.py,sha256=_B55WW2TD1fBINpabSSDRenVHXYmvlfhv-k8hJKU4lQ,3115
|
328
328
|
flwr/superexec/simulation.py,sha256=WQDon15oqpMopAZnwRZoTICYCfHqtkvFSqiTQ2hLD_g,4088
|
329
|
-
flwr_nightly-1.17.0.
|
330
|
-
flwr_nightly-1.17.0.
|
331
|
-
flwr_nightly-1.17.0.
|
332
|
-
flwr_nightly-1.17.0.
|
333
|
-
flwr_nightly-1.17.0.
|
329
|
+
flwr_nightly-1.17.0.dev20250316.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
330
|
+
flwr_nightly-1.17.0.dev20250316.dist-info/METADATA,sha256=TnKc9Jev3kwItLFLia2uS8FGkO_wKw1BrR0maimYi3Y,15877
|
331
|
+
flwr_nightly-1.17.0.dev20250316.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
332
|
+
flwr_nightly-1.17.0.dev20250316.dist-info/entry_points.txt,sha256=2-1L-GNKhwGw2_7_RoH55vHw2SIHjdAQy3HAVAWl9PY,374
|
333
|
+
flwr_nightly-1.17.0.dev20250316.dist-info/RECORD,,
|
{flwr_nightly-1.17.0.dev20250314.dist-info → flwr_nightly-1.17.0.dev20250316.dist-info}/LICENSE
RENAMED
File without changes
|
{flwr_nightly-1.17.0.dev20250314.dist-info → flwr_nightly-1.17.0.dev20250316.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|