flwr-nightly 1.20.0.dev20250721__py3-none-any.whl → 1.20.0.dev20250723__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 +1 -1
- flwr/common/exit/exit_code.py +5 -0
- flwr/common/record/array.py +16 -3
- flwr/common/record/arraychunk.py +0 -3
- flwr/server/grid/grpc_grid.py +9 -9
- flwr/supercore/object_store/object_store.py +4 -2
- flwr/supercore/scheduler/__init__.py +22 -0
- flwr/supercore/scheduler/plugin.py +71 -0
- flwr/supernode/scheduler/__init__.py +22 -0
- flwr/supernode/scheduler/simple_clientapp_scheduler_plugin.py +49 -0
- flwr/supernode/start_client_internal.py +13 -7
- {flwr_nightly-1.20.0.dev20250721.dist-info → flwr_nightly-1.20.0.dev20250723.dist-info}/METADATA +1 -1
- {flwr_nightly-1.20.0.dev20250721.dist-info → flwr_nightly-1.20.0.dev20250723.dist-info}/RECORD +15 -11
- {flwr_nightly-1.20.0.dev20250721.dist-info → flwr_nightly-1.20.0.dev20250723.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.20.0.dev20250721.dist-info → flwr_nightly-1.20.0.dev20250723.dist-info}/entry_points.txt +0 -0
flwr/common/constant.py
CHANGED
@@ -123,7 +123,7 @@ AUTHZ_TYPE_YAML_KEY = "authz_type" # For key name in YAML file
|
|
123
123
|
PUBLIC_KEY_HEADER = "flwr-public-key-bin" # Must end with "-bin" for binary data
|
124
124
|
SIGNATURE_HEADER = "flwr-signature-bin" # Must end with "-bin" for binary data
|
125
125
|
TIMESTAMP_HEADER = "flwr-timestamp"
|
126
|
-
TIMESTAMP_TOLERANCE =
|
126
|
+
TIMESTAMP_TOLERANCE = 300 # General tolerance for timestamp verification
|
127
127
|
SYSTEM_TIME_TOLERANCE = 5 # Allowance for system time drift
|
128
128
|
|
129
129
|
# Constants for grpc retry
|
flwr/common/exit/exit_code.py
CHANGED
@@ -31,6 +31,7 @@ class ExitCode:
|
|
31
31
|
SUPERLINK_THREAD_CRASH = 100
|
32
32
|
SUPERLINK_LICENSE_INVALID = 101
|
33
33
|
SUPERLINK_LICENSE_MISSING = 102
|
34
|
+
SUPERLINK_LICENSE_URL_INVALID = 103
|
34
35
|
|
35
36
|
# ServerApp-specific exit codes (200-299)
|
36
37
|
|
@@ -70,6 +71,10 @@ EXIT_CODE_HELP = {
|
|
70
71
|
"The license is missing. Please specify the license key by setting the "
|
71
72
|
"environment variable `FLWR_LICENSE_KEY`."
|
72
73
|
),
|
74
|
+
ExitCode.SUPERLINK_LICENSE_URL_INVALID: (
|
75
|
+
"The license URL is invalid. Please ensure that the `FLWR_LICENSE_URL` "
|
76
|
+
"environment variable is set to a valid URL."
|
77
|
+
),
|
73
78
|
# ServerApp-specific exit codes (200-299)
|
74
79
|
# SuperNode-specific exit codes (300-399)
|
75
80
|
ExitCode.SUPERNODE_REST_ADDRESS_INVALID: (
|
flwr/common/record/array.py
CHANGED
@@ -264,14 +264,22 @@ class Array(InflatableObject):
|
|
264
264
|
|
265
265
|
def slice_array(self) -> list[tuple[str, InflatableObject]]:
|
266
266
|
"""Slice Array data and construct a list of ArrayChunks."""
|
267
|
-
|
267
|
+
# Return cached chunks if they exist
|
268
|
+
if "_chunks" in self.__dict__:
|
269
|
+
return cast(list[tuple[str, InflatableObject]], self.__dict__["_chunks"])
|
270
|
+
|
271
|
+
# Chunks are not children as some of them may be identical
|
272
|
+
chunks: list[tuple[str, InflatableObject]] = []
|
268
273
|
# memoryview allows for zero-copy slicing
|
269
274
|
data_view = memoryview(self.data)
|
270
275
|
for start in range(0, len(data_view), MAX_ARRAY_CHUNK_SIZE):
|
271
276
|
end = min(start + MAX_ARRAY_CHUNK_SIZE, len(data_view))
|
272
277
|
ac = ArrayChunk(data_view[start:end])
|
273
|
-
|
274
|
-
|
278
|
+
chunks.append((ac.object_id, ac))
|
279
|
+
|
280
|
+
# Cache the chunks for future use
|
281
|
+
self.__dict__["_chunks"] = chunks
|
282
|
+
return chunks
|
275
283
|
|
276
284
|
def deflate(self) -> bytes:
|
277
285
|
"""Deflate the Array."""
|
@@ -386,4 +394,9 @@ class Array(InflatableObject):
|
|
386
394
|
if name in ("dtype", "shape", "stype", "data"):
|
387
395
|
# Mark as dirty if any of the main attributes are set
|
388
396
|
self.is_dirty = True
|
397
|
+
# Clear cached object ID
|
398
|
+
self.__dict__.pop("_object_id", None)
|
399
|
+
# Clear cached chunks if data is set
|
400
|
+
if name == "data":
|
401
|
+
self.__dict__.pop("_chunks", None)
|
389
402
|
super().__setattr__(name, value)
|
flwr/common/record/arraychunk.py
CHANGED
@@ -28,9 +28,6 @@ class ArrayChunk(InflatableObject):
|
|
28
28
|
|
29
29
|
data: memoryview
|
30
30
|
|
31
|
-
def __init__(self, data: bytes) -> None:
|
32
|
-
self.data = memoryview(data)
|
33
|
-
|
34
31
|
def deflate(self) -> bytes:
|
35
32
|
"""Deflate the ArrayChunk."""
|
36
33
|
return add_header_to_object_body(object_body=self.data, obj=self)
|
flwr/server/grid/grpc_grid.py
CHANGED
@@ -260,15 +260,15 @@ class GrpcGrid(Grid):
|
|
260
260
|
run_id = cast(Run, self._run).run_id
|
261
261
|
message_ids: list[str] = []
|
262
262
|
try:
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
263
|
+
with no_object_id_recompute():
|
264
|
+
for msg in messages:
|
265
|
+
# Populate metadata
|
266
|
+
msg.metadata.__dict__["_run_id"] = run_id
|
267
|
+
msg.metadata.__dict__["_src_node_id"] = self.node.node_id
|
268
|
+
msg.metadata.__dict__["_message_id"] = msg.object_id
|
269
|
+
# Check message
|
270
|
+
self._check_message(msg)
|
271
|
+
# Try pushing message and its objects
|
272
272
|
message_ids.append(self._try_push_message(run_id, msg))
|
273
273
|
|
274
274
|
except grpc.RpcError as e:
|
@@ -99,8 +99,10 @@ class ObjectStore(abc.ABC):
|
|
99
99
|
|
100
100
|
Returns
|
101
101
|
-------
|
102
|
-
bytes
|
103
|
-
The object stored under the given object_id.
|
102
|
+
Optional[bytes]
|
103
|
+
The object stored under the given object_id if it exists, else None.
|
104
|
+
The returned bytes will be b"" if the object is not yet available,
|
105
|
+
but has been preregistered.
|
104
106
|
"""
|
105
107
|
|
106
108
|
@abc.abstractmethod
|
@@ -0,0 +1,22 @@
|
|
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 App Scheduler."""
|
16
|
+
|
17
|
+
|
18
|
+
from .plugin import SchedulerPlugin
|
19
|
+
|
20
|
+
__all__ = [
|
21
|
+
"SchedulerPlugin",
|
22
|
+
]
|
@@ -0,0 +1,71 @@
|
|
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
|
+
"""Abstract base class SchedulerPlugin."""
|
16
|
+
|
17
|
+
|
18
|
+
from abc import ABC, abstractmethod
|
19
|
+
from collections.abc import Sequence
|
20
|
+
from typing import Callable, Optional
|
21
|
+
|
22
|
+
from flwr.common.typing import Run
|
23
|
+
|
24
|
+
|
25
|
+
class SchedulerPlugin(ABC):
|
26
|
+
"""Abstract base class for Scheduler plugins."""
|
27
|
+
|
28
|
+
def __init__(
|
29
|
+
self,
|
30
|
+
appio_api_address: str,
|
31
|
+
flwr_dir: str,
|
32
|
+
get_run: Callable[[int], Run],
|
33
|
+
) -> None:
|
34
|
+
self.appio_api_address = appio_api_address
|
35
|
+
self.flwr_dir = flwr_dir
|
36
|
+
self.get_run = get_run
|
37
|
+
|
38
|
+
@abstractmethod
|
39
|
+
def select_run_id(self, candidate_run_ids: Sequence[int]) -> Optional[int]:
|
40
|
+
"""Select a run ID to execute from a sequence of candidates.
|
41
|
+
|
42
|
+
A candidate run ID is one that has at least one pending message and is
|
43
|
+
not currently in progress (i.e., not associated with a token).
|
44
|
+
|
45
|
+
Parameters
|
46
|
+
----------
|
47
|
+
candidate_run_ids : Sequence[int]
|
48
|
+
A sequence of candidate run IDs to choose from.
|
49
|
+
|
50
|
+
Returns
|
51
|
+
-------
|
52
|
+
Optional[int]
|
53
|
+
The selected run ID, or None if no suitable candidate is found.
|
54
|
+
"""
|
55
|
+
|
56
|
+
@abstractmethod
|
57
|
+
def launch_app(self, token: str, run_id: int) -> None:
|
58
|
+
"""Launch the application associated with a given run ID and token.
|
59
|
+
|
60
|
+
This method starts the application process using the given `token`.
|
61
|
+
The `run_id` is used solely for bookkeeping purposes, allowing any
|
62
|
+
scheduler implementation to associate this launch with a specific run.
|
63
|
+
|
64
|
+
Parameters
|
65
|
+
----------
|
66
|
+
token : str
|
67
|
+
The token required to run the application.
|
68
|
+
run_id : int
|
69
|
+
The ID of the run associated with the token, used for tracking or
|
70
|
+
logging purposes.
|
71
|
+
"""
|
@@ -0,0 +1,22 @@
|
|
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 ClientApp Scheduler."""
|
16
|
+
|
17
|
+
|
18
|
+
from .simple_clientapp_scheduler_plugin import SimpleClientAppSchedulerPlugin
|
19
|
+
|
20
|
+
__all__ = [
|
21
|
+
"SimpleClientAppSchedulerPlugin",
|
22
|
+
]
|
@@ -0,0 +1,49 @@
|
|
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
|
+
"""Simple Flower ClientApp Scheduler plugin."""
|
16
|
+
|
17
|
+
|
18
|
+
import os
|
19
|
+
import subprocess
|
20
|
+
from collections.abc import Sequence
|
21
|
+
from typing import Optional
|
22
|
+
|
23
|
+
from flwr.supercore.scheduler import SchedulerPlugin
|
24
|
+
|
25
|
+
|
26
|
+
class SimpleClientAppSchedulerPlugin(SchedulerPlugin):
|
27
|
+
"""Simple Flower ClientApp Scheduler plugin.
|
28
|
+
|
29
|
+
The plugin always selects the first candidate run ID.
|
30
|
+
"""
|
31
|
+
|
32
|
+
def select_run_id(self, candidate_run_ids: Sequence[int]) -> Optional[int]:
|
33
|
+
"""Select a run ID to execute from a sequence of candidates."""
|
34
|
+
if not candidate_run_ids:
|
35
|
+
return None
|
36
|
+
return candidate_run_ids[0]
|
37
|
+
|
38
|
+
def launch_app(self, token: str, run_id: int) -> None:
|
39
|
+
"""Launch the application associated with a given run ID and token."""
|
40
|
+
cmds = ["flwr-clientapp", "--insecure"]
|
41
|
+
cmds += ["--clientappio-api-address", self.appio_api_address]
|
42
|
+
cmds += ["--token", token]
|
43
|
+
cmds += ["--parent-pid", str(os.getpid())]
|
44
|
+
cmds += ["--flwr-dir", self.flwr_dir]
|
45
|
+
# Launch the client app without waiting for it to complete.
|
46
|
+
# Since we don't need to manage the process, we intentionally avoid using
|
47
|
+
# a `with` statement. Suppress the pylint warning for it in this case.
|
48
|
+
# pylint: disable-next=consider-using-with
|
49
|
+
subprocess.Popen(cmds)
|
@@ -23,7 +23,7 @@ from contextlib import contextmanager
|
|
23
23
|
from functools import partial
|
24
24
|
from logging import INFO, WARN
|
25
25
|
from pathlib import Path
|
26
|
-
from typing import Callable, Optional, Union
|
26
|
+
from typing import Callable, Optional, Union, cast
|
27
27
|
|
28
28
|
import grpc
|
29
29
|
from cryptography.hazmat.primitives.asymmetric import ec
|
@@ -384,23 +384,29 @@ def _push_messages(
|
|
384
384
|
|
385
385
|
# Define the iterator for yielding object contents
|
386
386
|
# This will yield (object_id, content) pairs
|
387
|
-
def yield_object_contents(
|
387
|
+
def yield_object_contents(
|
388
|
+
_obj_tree: ObjectTree, obj_id_set: set[str]
|
389
|
+
) -> Iterator[tuple[str, bytes]]:
|
388
390
|
for tree in iterate_object_tree(_obj_tree):
|
389
|
-
|
391
|
+
if tree.object_id not in obj_id_set:
|
392
|
+
continue
|
393
|
+
while (content := object_store.get(tree.object_id)) == b"":
|
390
394
|
# Wait for the content to be available
|
391
395
|
time.sleep(0.5)
|
392
|
-
|
393
|
-
yield
|
396
|
+
# At this point, content is guaranteed to be available
|
397
|
+
# therefore we can yield it after casting it to bytes
|
398
|
+
yield tree.object_id, cast(bytes, content)
|
394
399
|
|
395
400
|
# Send the message
|
396
401
|
try:
|
397
402
|
# Send the reply message with its ObjectTree
|
398
|
-
send
|
403
|
+
# Get the IDs of objects to send
|
404
|
+
ids_obj_to_send = send(message, object_tree)
|
399
405
|
|
400
406
|
# Push object contents from the ObjectStore
|
401
407
|
run_id = message.metadata.run_id
|
402
408
|
push_object_contents_from_iterable(
|
403
|
-
yield_object_contents(object_tree),
|
409
|
+
yield_object_contents(object_tree, ids_obj_to_send),
|
404
410
|
# Use functools.partial to bind run_id explicitly,
|
405
411
|
# avoiding late binding issues and satisfying flake8 (B023)
|
406
412
|
# Equivalent to:
|
{flwr_nightly-1.20.0.dev20250721.dist-info → flwr_nightly-1.20.0.dev20250723.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.20.0.
|
3
|
+
Version: 1.20.0.dev20250723
|
4
4
|
Summary: Flower: A Friendly Federated AI Framework
|
5
5
|
License: Apache-2.0
|
6
6
|
Keywords: Artificial Intelligence,Federated AI,Federated Analytics,Federated Evaluation,Federated Learning,Flower,Machine Learning
|
{flwr_nightly-1.20.0.dev20250721.dist-info → flwr_nightly-1.20.0.dev20250723.dist-info}/RECORD
RENAMED
@@ -108,7 +108,7 @@ flwr/common/args.py,sha256=-aX_jVnSaDrJR2KZ8Wq0Y3dQHII4R4MJtJOIXzVUA0c,5417
|
|
108
108
|
flwr/common/auth_plugin/__init__.py,sha256=3rzPkVLn9WyB5n7HLk1XGDw3SLCqRWAU1_CnglcWPfw,970
|
109
109
|
flwr/common/auth_plugin/auth_plugin.py,sha256=kXx5o39vJchaPv28sK9qO6H_UXSWym6zRBbCa7sUwtQ,4825
|
110
110
|
flwr/common/config.py,sha256=glcZDjco-amw1YfQcYTFJ4S1pt9APoexT-mf1QscuHs,13960
|
111
|
-
flwr/common/constant.py,sha256=
|
111
|
+
flwr/common/constant.py,sha256=7BHHSoeNlOzweYyacI1DPLfyPhzN24C7VCA8j9pgA2A,8235
|
112
112
|
flwr/common/context.py,sha256=Be8obQR_OvEDy1OmshuUKxGRQ7Qx89mf5F4xlhkR10s,2407
|
113
113
|
flwr/common/date.py,sha256=1ZT2cRSpC2DJqprOVTLXYCR_O2_OZR0zXO_brJ3LqWc,1554
|
114
114
|
flwr/common/differential_privacy.py,sha256=FdlpdpPl_H_2HJa8CQM1iCUGBBQ5Dc8CzxmHERM-EoE,6148
|
@@ -118,7 +118,7 @@ flwr/common/event_log_plugin/__init__.py,sha256=ts3VAL3Fk6Grp1EK_1Qg_V-BfOof9F86
|
|
118
118
|
flwr/common/event_log_plugin/event_log_plugin.py,sha256=eK8OaDFagQRwqpb9eV0cJcm2ErtEBpMxFbhxJNx6n5w,2061
|
119
119
|
flwr/common/exit/__init__.py,sha256=-ZOJYLaNnR729a7VzZiFsLiqngzKQh3xc27svYStZ_Q,826
|
120
120
|
flwr/common/exit/exit.py,sha256=mJgbqMlVlwAgYtq-Vedj53wO4VxcDcy_P-GzqGK-1GQ,3452
|
121
|
-
flwr/common/exit/exit_code.py,sha256=
|
121
|
+
flwr/common/exit/exit_code.py,sha256=NbjJEywRb5YzDE7Xmo3Kd29inDEQbIUpskY9IEIGomE,4110
|
122
122
|
flwr/common/exit_handlers.py,sha256=IaqJ60fXZuu7McaRYnoYKtlbH9t4Yl9goNExKqtmQbs,4304
|
123
123
|
flwr/common/grpc.py,sha256=y70hUFvXkIf3l03xOhlb7qhS6W1UJZRSZqCdB0ir0v8,10381
|
124
124
|
flwr/common/heartbeat.py,sha256=SyEpNDnmJ0lni0cWO67rcoJVKasCLmkNHm3dKLeNrLU,5749
|
@@ -131,8 +131,8 @@ flwr/common/object_ref.py,sha256=p3SfTeqo3Aj16SkB-vsnNn01zswOPdGNBitcbRnqmUk,913
|
|
131
131
|
flwr/common/parameter.py,sha256=UVw6sOgehEFhFs4uUCMl2kfVq1PD6ncmWgPLMsZPKPE,2095
|
132
132
|
flwr/common/pyproject.py,sha256=2SU6yJW7059SbMXgzjOdK1GZRWO6AixDH7BmdxbMvHI,1386
|
133
133
|
flwr/common/record/__init__.py,sha256=cNGccdDoxttqgnUgyKRIqLWULjW-NaSmOufVxtXq-sw,1197
|
134
|
-
flwr/common/record/array.py,sha256=
|
135
|
-
flwr/common/record/arraychunk.py,sha256=
|
134
|
+
flwr/common/record/array.py,sha256=6ybCfUZ13zI_CZKETUAVhIwlmbEGj4k6JazvVX5rOPw,15038
|
135
|
+
flwr/common/record/arraychunk.py,sha256=gU5h6uP7H_06Z14wNixtwH2FvepQkl9FpALXg9qcbhM,1936
|
136
136
|
flwr/common/record/arrayrecord.py,sha256=CpoqYXM6Iv4XEc9SryCMYmw-bIvP8ut6xWJzRwYJzdU,18008
|
137
137
|
flwr/common/record/configrecord.py,sha256=G7U0q39kB0Kyi0zMxFmPxcVemL9NgwVS1qjvI4BRQuU,9763
|
138
138
|
flwr/common/record/conversion_utils.py,sha256=wbNCzy7oAqaA3-arhls_EqRZYXRC4YrWIoE-Gy82fJ0,1191
|
@@ -242,7 +242,7 @@ flwr/server/criterion.py,sha256=G4e-6B48Pc7d5rmGVUpIzNKb6UF88O3VmTRuUltgjzM,1061
|
|
242
242
|
flwr/server/fleet_event_log_interceptor.py,sha256=gtVPr2yQp3U2GnabIdFnuok18VerEcidKj1lKmDYGoY,3950
|
243
243
|
flwr/server/grid/__init__.py,sha256=aWZHezoR2UGMJISB_gPMCm2N_2GSbm97A3lAp7ruhRQ,888
|
244
244
|
flwr/server/grid/grid.py,sha256=naGCYt5J6dnmUvrcGkdNyKPe3MBd-0awGm1ALmgahqY,6625
|
245
|
-
flwr/server/grid/grpc_grid.py,sha256=
|
245
|
+
flwr/server/grid/grpc_grid.py,sha256=WmtBvIKOlvH4sVj6HdkJKzAfWhBLgaQJKYNWxybYWmM,13763
|
246
246
|
flwr/server/grid/inmemory_grid.py,sha256=RjejYT-d-hHuTs1KSs_5wvOdAWKLus8w5_UAcnGt4iw,6168
|
247
247
|
flwr/server/history.py,sha256=cCkFhBN4GoHsYYNk5GG1Y089eKJh2DH_ZJbYPwLaGyk,5026
|
248
248
|
flwr/server/run_serverapp.py,sha256=v0p6jXj2dFxlRUdoEeF1mnaFd9XRQi6dZCflPY6d3qI,2063
|
@@ -341,9 +341,11 @@ flwr/supercore/license_plugin/__init__.py,sha256=d8OgHTn2BwjoNSPy8jQQxTC_iT3-ENL
|
|
341
341
|
flwr/supercore/license_plugin/license_plugin.py,sha256=BFhlCH5v9KKuY7crVCsi8fuYe98SJfnGxRS0CVc_Y5I,948
|
342
342
|
flwr/supercore/object_store/__init__.py,sha256=cdfPAmjINY6iOp8oI_LdcVh2simg469Mkdl4LLV4kHI,911
|
343
343
|
flwr/supercore/object_store/in_memory_object_store.py,sha256=CGY43syxDGrUPcdOzRH3hNrfeqmoTOY_wjo3qaAHuNk,9612
|
344
|
-
flwr/supercore/object_store/object_store.py,sha256=
|
344
|
+
flwr/supercore/object_store/object_store.py,sha256=J-rI3X7ET-F6dqOyM-UfHKCCQtPJ_EnYW62H_1txts0,5252
|
345
345
|
flwr/supercore/object_store/object_store_factory.py,sha256=QVwE2ywi7vsj2iKfvWWnNw3N_I7Rz91NUt2RpcbJ7iM,1527
|
346
346
|
flwr/supercore/object_store/utils.py,sha256=-WwBa6ejMNm9ahmNZP39IHutS0cwingmeqCoxTmATQM,1845
|
347
|
+
flwr/supercore/scheduler/__init__.py,sha256=E4GviiNJoZKz1dOao8ZGRHExsiM23GtOrkpMrTHy3n8,787
|
348
|
+
flwr/supercore/scheduler/plugin.py,sha256=kIv0JUrHP-ghrcGT-pbporL9A2mUz8PxASw6KgxCRv8,2460
|
347
349
|
flwr/supercore/utils.py,sha256=ebuHMbeA8eXisX0oMPqBK3hk7uVnIE_yiqWVz8YbkpQ,1324
|
348
350
|
flwr/superexec/__init__.py,sha256=YFqER0IJc1XEWfsX6AxZ9LSRq0sawPYrNYki-brvTIc,715
|
349
351
|
flwr/superexec/app.py,sha256=U2jjOHb2LGWoU7vrl9_czTzre9O2mPxu3CPGUZ86sK4,1465
|
@@ -366,11 +368,13 @@ flwr/supernode/nodestate/nodestate.py,sha256=kkGFxYnLIwT4-UmlPnf6HvAUpPey2urUNrw
|
|
366
368
|
flwr/supernode/nodestate/nodestate_factory.py,sha256=UYTDCcwK_baHUmkzkJDxL0UEqvtTfOMlQRrROMCd0Xo,1430
|
367
369
|
flwr/supernode/runtime/__init__.py,sha256=JQdqd2EMTn-ORMeTvewYYh52ls0YKP68jrps1qioxu4,718
|
368
370
|
flwr/supernode/runtime/run_clientapp.py,sha256=woAO8rXclt5eZeNHokhBChgxMf-TAzqWnHCkoiSsLVs,10765
|
371
|
+
flwr/supernode/scheduler/__init__.py,sha256=nQLi5ROVCMz8ii_WsZn4MAqKHXI40Eb3tq5-9zZbmpg,850
|
372
|
+
flwr/supernode/scheduler/simple_clientapp_scheduler_plugin.py,sha256=nnNuKhelrAEGCnWZ3aAkqJrhPu7xlVQ-oO1Eih9shTU,2000
|
369
373
|
flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca8gxdEo,717
|
370
374
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
|
371
375
|
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=SOx719uqdkIHryBri-XpuYpALQE__hxNtDjSAdeUtug,10059
|
372
|
-
flwr/supernode/start_client_internal.py,sha256=
|
373
|
-
flwr_nightly-1.20.0.
|
374
|
-
flwr_nightly-1.20.0.
|
375
|
-
flwr_nightly-1.20.0.
|
376
|
-
flwr_nightly-1.20.0.
|
376
|
+
flwr/supernode/start_client_internal.py,sha256=j0tGOaki1LNNMKzvnb2h8mGM0nE3ys-GzwAh0r6rgWI,21731
|
377
|
+
flwr_nightly-1.20.0.dev20250723.dist-info/METADATA,sha256=TZhBkek0rvMIVa0ae2M_u3fAdo3-phWakrtXgP320qg,15966
|
378
|
+
flwr_nightly-1.20.0.dev20250723.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
379
|
+
flwr_nightly-1.20.0.dev20250723.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
|
380
|
+
flwr_nightly-1.20.0.dev20250723.dist-info/RECORD,,
|
{flwr_nightly-1.20.0.dev20250721.dist-info → flwr_nightly-1.20.0.dev20250723.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|