flwr-nightly 1.15.0.dev20250130__py3-none-any.whl → 1.15.2.dev20250215__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/cli/auth_plugin/oidc_cli_plugin.py +2 -2
- flwr/cli/ls.py +3 -2
- flwr/cli/new/templates/app/README.baseline.md.tpl +4 -4
- flwr/cli/new/templates/app/README.md.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
- flwr/cli/stop.py +3 -2
- flwr/cli/utils.py +2 -2
- flwr/client/supernode/app.py +4 -28
- flwr/common/args.py +25 -47
- flwr/common/config.py +15 -2
- flwr/common/constant.py +9 -7
- flwr/common/exit_handlers.py +17 -29
- flwr/common/object_ref.py +0 -14
- flwr/proto/task_pb2.py +6 -6
- flwr/proto/task_pb2.pyi +1 -4
- flwr/server/app.py +5 -9
- flwr/server/driver/inmemory_driver.py +0 -1
- flwr/server/superlink/driver/serverappio_servicer.py +1 -5
- flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +17 -4
- flwr/server/superlink/fleet/message_handler/message_handler.py +0 -4
- flwr/server/superlink/fleet/vce/vce_api.py +0 -1
- flwr/server/superlink/linkstate/sqlite_linkstate.py +0 -6
- flwr/server/utils/validator.py +0 -3
- {flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/METADATA +2 -2
- {flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/RECORD +36 -36
- {flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/entry_points.txt +0 -0
@@ -26,7 +26,7 @@ import typer
|
|
26
26
|
from flwr.common.auth_plugin import CliAuthPlugin
|
27
27
|
from flwr.common.constant import (
|
28
28
|
ACCESS_TOKEN_KEY,
|
29
|
-
|
29
|
+
AUTH_TYPE_JSON_KEY,
|
30
30
|
REFRESH_TOKEN_KEY,
|
31
31
|
AuthType,
|
32
32
|
)
|
@@ -97,7 +97,7 @@ class OidcCliPlugin(CliAuthPlugin):
|
|
97
97
|
self.access_token = credentials.access_token
|
98
98
|
self.refresh_token = credentials.refresh_token
|
99
99
|
json_dict = {
|
100
|
-
|
100
|
+
AUTH_TYPE_JSON_KEY: AuthType.OIDC,
|
101
101
|
ACCESS_TOKEN_KEY: credentials.access_token,
|
102
102
|
REFRESH_TOKEN_KEY: credentials.refresh_token,
|
103
103
|
}
|
flwr/cli/ls.py
CHANGED
@@ -117,7 +117,7 @@ def ls( # pylint: disable=too-many-locals, too-many-branches, R0913, R0917
|
|
117
117
|
federation, config, federation_config_overrides
|
118
118
|
)
|
119
119
|
exit_if_no_address(federation_config, "ls")
|
120
|
-
|
120
|
+
channel = None
|
121
121
|
try:
|
122
122
|
if runs and run_id is not None:
|
123
123
|
raise ValueError(
|
@@ -148,7 +148,8 @@ def ls( # pylint: disable=too-many-locals, too-many-branches, R0913, R0917
|
|
148
148
|
)
|
149
149
|
raise typer.Exit(code=1) from err
|
150
150
|
finally:
|
151
|
-
channel
|
151
|
+
if channel:
|
152
|
+
channel.close()
|
152
153
|
except (typer.Exit, Exception) as err: # pylint: disable=broad-except
|
153
154
|
if suppress_output:
|
154
155
|
restore_output()
|
@@ -13,7 +13,7 @@ dataset: [dataset1, dataset2] # TODO: list of datasets you include in your basel
|
|
13
13
|
|
14
14
|
> [!IMPORTANT]
|
15
15
|
> To help having all baselines similarly formatted and structured, we have included two scripts in `baselines/dev` that when run will format your code and run some tests checking if it's formatted.
|
16
|
-
> These checks use standard packages such as `isort`, `black`, `pylint` and others. You as a baseline creator will need to install additional
|
16
|
+
> These checks use standard packages such as `isort`, `black`, `pylint` and others. You as a baseline creator will need to install additional packages. These are already specified in the `pyproject.toml` of
|
17
17
|
> your baseline. Follow these steps:
|
18
18
|
|
19
19
|
```bash
|
@@ -66,9 +66,9 @@ cd .. # so you are in the `flower/baselines` directory
|
|
66
66
|
|
67
67
|
## About this baseline
|
68
68
|
|
69
|
-
**What’s implemented:** :warning: *_Concisely describe what experiment(s) (e.g. Figure 1, Table 2, etc) in the publication can be replicated by running the code. Please only use a few sentences. ”_*
|
69
|
+
**What’s implemented:** :warning: *_Concisely describe what experiment(s) (e.g. Figure 1, Table 2, etc.) in the publication can be replicated by running the code. Please only use a few sentences. ”_*
|
70
70
|
|
71
|
-
**Datasets:** :warning: *_List the datasets you used (if you used a medium to large dataset, >10GB please also include the sizes of the dataset). We highly recommend using [FlowerDatasets](https://flower.ai/docs/datasets/index.html) to download and partition your dataset. If you have other ways to download the data, you can also use `FlowerDatasets` to
|
71
|
+
**Datasets:** :warning: *_List the datasets you used (if you used a medium to large dataset, >10GB please also include the sizes of the dataset). We highly recommend using [FlowerDatasets](https://flower.ai/docs/datasets/index.html) to download and partition your dataset. If you have other ways to download the data, you can also use `FlowerDatasets` to partition it._*
|
72
72
|
|
73
73
|
**Hardware Setup:** :warning: *_Give some details about the hardware (e.g. a server with 8x V100 32GB and 256GB of RAM) you used to run the experiments for this baseline. Indicate how long it took to run the experiments. Someone out there might not have access to the same resources you have so, could you list the absolute minimum hardware needed to run the experiment in a reasonable amount of time ? (e.g. minimum is 1x 16GB GPU otherwise a client model can’t be trained with a sufficiently large batch size). Could you test this works too?_*
|
74
74
|
|
@@ -122,6 +122,6 @@ flwr run . --run-config learning-rate=0.1,coefficient=0.123
|
|
122
122
|
flwr run . --run-config <my-big-experiment-config>.toml
|
123
123
|
```
|
124
124
|
|
125
|
-
:warning: _It is preferable to show a single
|
125
|
+
:warning: _It is preferable to show a single command (or multiple commands if they belong to the same experiment) and then a table/plot with the expected results, instead of showing all the commands first and then all the results/plots._
|
126
126
|
:warning: _If you present plots or other figures, please include either a Jupyter notebook showing how to create them or include a utility function that can be called after the experiments finish running._
|
127
127
|
:warning: If you include plots or figures, save them in `.png` format and place them in a new directory named `_static` at the same level as your `README.md`.
|
@@ -18,7 +18,7 @@ Refer to the [How to Run Simulations](https://flower.ai/docs/framework/how-to-ru
|
|
18
18
|
|
19
19
|
## Run with the Deployment Engine
|
20
20
|
|
21
|
-
Follow this [how-to guide](https://flower.ai/docs/framework/how-to-run-flower-with-deployment-engine.html) to run the same app in this example but with Flower's Deployment Engine. After that, you might be
|
21
|
+
Follow this [how-to guide](https://flower.ai/docs/framework/how-to-run-flower-with-deployment-engine.html) to run the same app in this example but with Flower's Deployment Engine. After that, you might be interested in setting up [secure TLS-enabled communications](https://flower.ai/docs/framework/how-to-enable-tls-connections.html) and [SuperNode authentication](https://flower.ai/docs/framework/how-to-authenticate-supernodes.html) in your federation.
|
22
22
|
|
23
23
|
You can run Flower on Docker too! Check out the [Flower with Docker](https://flower.ai/docs/framework/docker/index.html) documentation.
|
24
24
|
|
flwr/cli/stop.py
CHANGED
@@ -84,7 +84,7 @@ def stop( # pylint: disable=R0914
|
|
84
84
|
federation, config, federation_config_overrides
|
85
85
|
)
|
86
86
|
exit_if_no_address(federation_config, "stop")
|
87
|
-
|
87
|
+
channel = None
|
88
88
|
try:
|
89
89
|
auth_plugin = try_obtain_cli_auth_plugin(app, federation, federation_config)
|
90
90
|
channel = init_channel(app, federation_config, auth_plugin)
|
@@ -101,7 +101,8 @@ def stop( # pylint: disable=R0914
|
|
101
101
|
)
|
102
102
|
raise typer.Exit(code=1) from err
|
103
103
|
finally:
|
104
|
-
channel
|
104
|
+
if channel:
|
105
|
+
channel.close()
|
105
106
|
except (typer.Exit, Exception) as err: # pylint: disable=broad-except
|
106
107
|
if suppress_output:
|
107
108
|
restore_output()
|
flwr/cli/utils.py
CHANGED
@@ -28,7 +28,7 @@ import typer
|
|
28
28
|
|
29
29
|
from flwr.cli.cli_user_auth_interceptor import CliUserAuthInterceptor
|
30
30
|
from flwr.common.auth_plugin import CliAuthPlugin
|
31
|
-
from flwr.common.constant import
|
31
|
+
from flwr.common.constant import AUTH_TYPE_JSON_KEY, CREDENTIALS_DIR, FLWR_DIR
|
32
32
|
from flwr.common.grpc import (
|
33
33
|
GRPC_MAX_MESSAGE_LENGTH,
|
34
34
|
create_channel,
|
@@ -239,7 +239,7 @@ def try_obtain_cli_auth_plugin(
|
|
239
239
|
try:
|
240
240
|
with config_path.open("r", encoding="utf-8") as file:
|
241
241
|
json_file = json.load(file)
|
242
|
-
auth_type = json_file[
|
242
|
+
auth_type = json_file[AUTH_TYPE_JSON_KEY]
|
243
243
|
except (FileNotFoundError, KeyError):
|
244
244
|
typer.secho(
|
245
245
|
"❌ Missing or invalid credentials for user authentication. "
|
flwr/client/supernode/app.py
CHANGED
@@ -41,7 +41,7 @@ from flwr.common.constant import (
|
|
41
41
|
)
|
42
42
|
from flwr.common.exit import ExitCode, flwr_exit
|
43
43
|
from flwr.common.exit_handlers import register_exit_handlers
|
44
|
-
from flwr.common.logger import log
|
44
|
+
from flwr.common.logger import log
|
45
45
|
|
46
46
|
from ..app import start_client_internal
|
47
47
|
from ..clientapp.utils import get_load_client_app_fn
|
@@ -50,7 +50,6 @@ from ..clientapp.utils import get_load_client_app_fn
|
|
50
50
|
def run_supernode() -> None:
|
51
51
|
"""Run Flower SuperNode."""
|
52
52
|
args = _parse_args_run_supernode().parse_args()
|
53
|
-
_warn_deprecated_server_arg(args)
|
54
53
|
|
55
54
|
log(INFO, "Starting Flower SuperNode")
|
56
55
|
|
@@ -109,26 +108,6 @@ def run_client_app() -> None:
|
|
109
108
|
register_exit_handlers(event_type=EventType.RUN_CLIENT_APP_LEAVE)
|
110
109
|
|
111
110
|
|
112
|
-
def _warn_deprecated_server_arg(args: argparse.Namespace) -> None:
|
113
|
-
"""Warn about the deprecated argument `--server`."""
|
114
|
-
if args.server != FLEET_API_GRPC_RERE_DEFAULT_ADDRESS:
|
115
|
-
warn = "Passing flag --server is deprecated. Use --superlink instead."
|
116
|
-
warn_deprecated_feature(warn)
|
117
|
-
|
118
|
-
if args.superlink != FLEET_API_GRPC_RERE_DEFAULT_ADDRESS:
|
119
|
-
# if `--superlink` also passed, then
|
120
|
-
# warn user that this argument overrides what was passed with `--server`
|
121
|
-
log(
|
122
|
-
WARN,
|
123
|
-
"Both `--server` and `--superlink` were passed. "
|
124
|
-
"`--server` will be ignored. Connecting to the Superlink Fleet API "
|
125
|
-
"at %s.",
|
126
|
-
args.superlink,
|
127
|
-
)
|
128
|
-
else:
|
129
|
-
args.superlink = args.server
|
130
|
-
|
131
|
-
|
132
111
|
def _parse_args_run_supernode() -> argparse.ArgumentParser:
|
133
112
|
"""Parse flower-supernode command line arguments."""
|
134
113
|
parser = argparse.ArgumentParser(
|
@@ -206,15 +185,12 @@ def _parse_args_common(parser: argparse.ArgumentParser) -> None:
|
|
206
185
|
help="Specifies the path to the PEM-encoded root certificate file for "
|
207
186
|
"establishing secure HTTPS connections.",
|
208
187
|
)
|
209
|
-
parser.add_argument(
|
210
|
-
"--server",
|
211
|
-
default=FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
|
212
|
-
help="Server address",
|
213
|
-
)
|
214
188
|
parser.add_argument(
|
215
189
|
"--superlink",
|
216
190
|
default=FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
|
217
|
-
help="SuperLink Fleet API
|
191
|
+
help="SuperLink Fleet API address (IPv4, IPv6, or a domain name). If using the "
|
192
|
+
"REST (experimental) transport, ensure your address is in the form "
|
193
|
+
"`http://...` or `https://...` when TLS is enabled.",
|
218
194
|
)
|
219
195
|
parser.add_argument(
|
220
196
|
"--max-retries",
|
flwr/common/args.py
CHANGED
@@ -20,13 +20,9 @@ import sys
|
|
20
20
|
from logging import DEBUG, ERROR, WARN
|
21
21
|
from os.path import isfile
|
22
22
|
from pathlib import Path
|
23
|
-
from typing import Optional
|
23
|
+
from typing import Optional, Union
|
24
24
|
|
25
|
-
from flwr.common.constant import
|
26
|
-
TRANSPORT_TYPE_GRPC_ADAPTER,
|
27
|
-
TRANSPORT_TYPE_GRPC_RERE,
|
28
|
-
TRANSPORT_TYPE_REST,
|
29
|
-
)
|
25
|
+
from flwr.common.constant import TRANSPORT_TYPE_REST
|
30
26
|
from flwr.common.logger import log
|
31
27
|
|
32
28
|
|
@@ -55,9 +51,9 @@ def add_args_flwr_app_common(parser: argparse.ArgumentParser) -> None:
|
|
55
51
|
def try_obtain_root_certificates(
|
56
52
|
args: argparse.Namespace,
|
57
53
|
grpc_server_address: str,
|
58
|
-
) -> Optional[bytes]:
|
54
|
+
) -> Optional[Union[bytes, str]]:
|
59
55
|
"""Validate and return the root certificates."""
|
60
|
-
root_cert_path = args.root_certificates
|
56
|
+
root_cert_path: Optional[str] = args.root_certificates
|
61
57
|
if args.insecure:
|
62
58
|
if root_cert_path is not None:
|
63
59
|
sys.exit(
|
@@ -93,56 +89,38 @@ def try_obtain_root_certificates(
|
|
93
89
|
grpc_server_address,
|
94
90
|
root_cert_path,
|
95
91
|
)
|
92
|
+
if args.transport == TRANSPORT_TYPE_REST:
|
93
|
+
return root_cert_path
|
96
94
|
return root_certificates
|
97
95
|
|
98
96
|
|
99
97
|
def try_obtain_server_certificates(
|
100
98
|
args: argparse.Namespace,
|
101
|
-
transport_type: str,
|
102
99
|
) -> Optional[tuple[bytes, bytes, bytes]]:
|
103
100
|
"""Validate and return the CA cert, server cert, and server private key."""
|
104
101
|
if args.insecure:
|
105
102
|
log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.")
|
106
103
|
return None
|
107
104
|
# Check if certificates are provided
|
108
|
-
if
|
109
|
-
if
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
)
|
128
|
-
if transport_type == TRANSPORT_TYPE_REST:
|
129
|
-
if args.ssl_certfile and args.ssl_keyfile:
|
130
|
-
if not isfile(args.ssl_certfile):
|
131
|
-
sys.exit("Path argument `--ssl-certfile` does not point to a file.")
|
132
|
-
if not isfile(args.ssl_keyfile):
|
133
|
-
sys.exit("Path argument `--ssl-keyfile` does not point to a file.")
|
134
|
-
certificates = (
|
135
|
-
b"",
|
136
|
-
Path(args.ssl_certfile).read_bytes(), # server certificate
|
137
|
-
Path(args.ssl_keyfile).read_bytes(), # server private key
|
138
|
-
)
|
139
|
-
return certificates
|
140
|
-
if args.ssl_certfile or args.ssl_keyfile:
|
141
|
-
sys.exit(
|
142
|
-
"You need to provide valid file paths to `--ssl-certfile` "
|
143
|
-
"and `--ssl-keyfile` to create a secure connection "
|
144
|
-
"in Fleet API server (REST, experimental)."
|
145
|
-
)
|
105
|
+
if args.ssl_certfile and args.ssl_keyfile and args.ssl_ca_certfile:
|
106
|
+
if not isfile(args.ssl_ca_certfile):
|
107
|
+
sys.exit("Path argument `--ssl-ca-certfile` does not point to a file.")
|
108
|
+
if not isfile(args.ssl_certfile):
|
109
|
+
sys.exit("Path argument `--ssl-certfile` does not point to a file.")
|
110
|
+
if not isfile(args.ssl_keyfile):
|
111
|
+
sys.exit("Path argument `--ssl-keyfile` does not point to a file.")
|
112
|
+
certificates = (
|
113
|
+
Path(args.ssl_ca_certfile).read_bytes(), # CA certificate
|
114
|
+
Path(args.ssl_certfile).read_bytes(), # server certificate
|
115
|
+
Path(args.ssl_keyfile).read_bytes(), # server private key
|
116
|
+
)
|
117
|
+
return certificates
|
118
|
+
if args.ssl_certfile or args.ssl_keyfile or args.ssl_ca_certfile:
|
119
|
+
sys.exit(
|
120
|
+
"You need to provide valid file paths to `--ssl-certfile`, "
|
121
|
+
"`--ssl-keyfile`, and `—-ssl-ca-certfile` to create a secure "
|
122
|
+
"connection in Fleet API server (gRPC-rere)."
|
123
|
+
)
|
146
124
|
log(
|
147
125
|
ERROR,
|
148
126
|
"Certificates are required unless running in insecure mode. "
|
flwr/common/config.py
CHANGED
@@ -23,6 +23,7 @@ from pathlib import Path
|
|
23
23
|
from typing import IO, Any, Optional, TypeVar, Union, cast, get_args
|
24
24
|
|
25
25
|
import tomli
|
26
|
+
import typer
|
26
27
|
|
27
28
|
from flwr.common.constant import (
|
28
29
|
APP_DIR,
|
@@ -233,8 +234,20 @@ def parse_config_args(
|
|
233
234
|
|
234
235
|
matches = pattern.findall(config_line)
|
235
236
|
toml_str = "\n".join(f"{k} = {v}" for k, v in matches)
|
236
|
-
|
237
|
-
|
237
|
+
try:
|
238
|
+
overrides.update(tomli.loads(toml_str))
|
239
|
+
flat_overrides = flatten_dict(overrides) if flatten else overrides
|
240
|
+
except tomli.TOMLDecodeError as err:
|
241
|
+
typer.secho(
|
242
|
+
"❌ The provided configuration string is in an invalid format. "
|
243
|
+
"The correct format should be, e.g., 'key1=123 key2=false "
|
244
|
+
'key3="string"\', where values must be of type bool, int, '
|
245
|
+
"string, or float. Ensure proper formatting with "
|
246
|
+
"space-separated key-value pairs.",
|
247
|
+
fg=typer.colors.RED,
|
248
|
+
bold=True,
|
249
|
+
)
|
250
|
+
raise typer.Exit(code=1) from err
|
238
251
|
|
239
252
|
return flat_overrides
|
240
253
|
|
flwr/common/constant.py
CHANGED
@@ -108,15 +108,17 @@ MAX_RETRY_DELAY = 20 # Maximum delay duration between two consecutive retries.
|
|
108
108
|
|
109
109
|
# Constants for user authentication
|
110
110
|
CREDENTIALS_DIR = ".credentials"
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
AUTH_TYPE_JSON_KEY = "auth-type" # For key name in JSON file
|
112
|
+
AUTH_TYPE_YAML_KEY = "auth_type" # For key name in YAML file
|
113
|
+
ACCESS_TOKEN_KEY = "flwr-oidc-access-token"
|
114
|
+
REFRESH_TOKEN_KEY = "flwr-oidc-refresh-token"
|
114
115
|
|
115
116
|
# Constants for node authentication
|
116
|
-
PUBLIC_KEY_HEADER = "public-key-bin" # Must end with "-bin" for binary data
|
117
|
-
SIGNATURE_HEADER = "signature-bin" # Must end with "-bin" for binary data
|
118
|
-
TIMESTAMP_HEADER = "timestamp"
|
119
|
-
TIMESTAMP_TOLERANCE = 10 #
|
117
|
+
PUBLIC_KEY_HEADER = "flwr-public-key-bin" # Must end with "-bin" for binary data
|
118
|
+
SIGNATURE_HEADER = "flwr-signature-bin" # Must end with "-bin" for binary data
|
119
|
+
TIMESTAMP_HEADER = "flwr-timestamp"
|
120
|
+
TIMESTAMP_TOLERANCE = 10 # General tolerance for timestamp verification
|
121
|
+
SYSTEM_TIME_TOLERANCE = 5 # Allowance for system time drift
|
120
122
|
|
121
123
|
|
122
124
|
class MessageType:
|
flwr/common/exit_handlers.py
CHANGED
@@ -15,10 +15,10 @@
|
|
15
15
|
"""Common function to register exit handlers for server and client."""
|
16
16
|
|
17
17
|
|
18
|
-
|
18
|
+
import signal
|
19
19
|
from threading import Thread
|
20
20
|
from types import FrameType
|
21
|
-
from typing import Optional
|
21
|
+
from typing import Callable, Optional
|
22
22
|
|
23
23
|
from grpc import Server
|
24
24
|
|
@@ -26,12 +26,15 @@ from flwr.common.telemetry import EventType
|
|
26
26
|
|
27
27
|
from .exit import ExitCode, flwr_exit
|
28
28
|
|
29
|
-
SIGNAL_TO_EXIT_CODE = {
|
30
|
-
SIGINT: ExitCode.GRACEFUL_EXIT_SIGINT,
|
31
|
-
|
32
|
-
SIGTERM: ExitCode.GRACEFUL_EXIT_SIGTERM,
|
29
|
+
SIGNAL_TO_EXIT_CODE: dict[int, int] = {
|
30
|
+
signal.SIGINT: ExitCode.GRACEFUL_EXIT_SIGINT,
|
31
|
+
signal.SIGTERM: ExitCode.GRACEFUL_EXIT_SIGTERM,
|
33
32
|
}
|
34
33
|
|
34
|
+
# SIGQUIT is not available on Windows
|
35
|
+
if hasattr(signal, "SIGQUIT"):
|
36
|
+
SIGNAL_TO_EXIT_CODE[signal.SIGQUIT] = ExitCode.GRACEFUL_EXIT_SIGQUIT
|
37
|
+
|
35
38
|
|
36
39
|
def register_exit_handlers(
|
37
40
|
event_type: EventType,
|
@@ -54,23 +57,16 @@ def register_exit_handlers(
|
|
54
57
|
An optional list of threads that need to be gracefully
|
55
58
|
terminated before exiting.
|
56
59
|
"""
|
57
|
-
default_handlers = {
|
58
|
-
|
59
|
-
|
60
|
-
SIGTERM: None,
|
61
|
-
}
|
62
|
-
|
63
|
-
def graceful_exit_handler( # type: ignore
|
64
|
-
signalnum,
|
65
|
-
frame: FrameType, # pylint: disable=unused-argument
|
66
|
-
) -> None:
|
60
|
+
default_handlers: dict[int, Callable[[int, FrameType], None]] = {}
|
61
|
+
|
62
|
+
def graceful_exit_handler(signalnum: int, _frame: FrameType) -> None:
|
67
63
|
"""Exit handler to be registered with `signal.signal`.
|
68
64
|
|
69
65
|
When called will reset signal handler to original signal handler from
|
70
66
|
default_handlers.
|
71
67
|
"""
|
72
68
|
# Reset to default handler
|
73
|
-
signal(signalnum, default_handlers[signalnum])
|
69
|
+
signal.signal(signalnum, default_handlers[signalnum]) # type: ignore
|
74
70
|
|
75
71
|
if grpc_servers is not None:
|
76
72
|
for grpc_server in grpc_servers:
|
@@ -87,15 +83,7 @@ def register_exit_handlers(
|
|
87
83
|
event_type=event_type,
|
88
84
|
)
|
89
85
|
|
90
|
-
|
91
|
-
|
92
|
-
graceful_exit_handler
|
93
|
-
|
94
|
-
default_handlers[SIGQUIT] = signal( # type: ignore
|
95
|
-
SIGQUIT,
|
96
|
-
graceful_exit_handler, # type: ignore
|
97
|
-
)
|
98
|
-
default_handlers[SIGTERM] = signal( # type: ignore
|
99
|
-
SIGTERM,
|
100
|
-
graceful_exit_handler, # type: ignore
|
101
|
-
)
|
86
|
+
# Register signal handlers
|
87
|
+
for sig in SIGNAL_TO_EXIT_CODE:
|
88
|
+
default_handler = signal.signal(sig, graceful_exit_handler) # type: ignore
|
89
|
+
default_handlers[sig] = default_handler # type: ignore
|
flwr/common/object_ref.py
CHANGED
@@ -19,13 +19,10 @@ import ast
|
|
19
19
|
import importlib
|
20
20
|
import sys
|
21
21
|
from importlib.util import find_spec
|
22
|
-
from logging import WARN
|
23
22
|
from pathlib import Path
|
24
23
|
from threading import Lock
|
25
24
|
from typing import Any, Optional, Union
|
26
25
|
|
27
|
-
from .logger import log
|
28
|
-
|
29
26
|
OBJECT_REF_HELP_STR = """
|
30
27
|
\n\nThe object reference string should have the form <module>:<attribute>. Valid
|
31
28
|
examples include `client:app` and `project.package.module:wrapper.app`. It must
|
@@ -171,17 +168,6 @@ def load_app( # pylint: disable= too-many-branches
|
|
171
168
|
# Import the module
|
172
169
|
if module_str not in sys.modules:
|
173
170
|
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
171
|
else:
|
186
172
|
module = sys.modules[module_str]
|
187
173
|
_reload_modules(project_dir)
|
flwr/proto/task_pb2.py
CHANGED
@@ -17,7 +17,7 @@ from flwr.proto import recordset_pb2 as flwr_dot_proto_dot_recordset__pb2
|
|
17
17
|
from flwr.proto import error_pb2 as flwr_dot_proto_dot_error__pb2
|
18
18
|
|
19
19
|
|
20
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/task.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x16\x66lwr/proto/error.proto\"\
|
20
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/task.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x16\x66lwr/proto/error.proto\"\xf6\x01\n\x04Task\x12\"\n\x08producer\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\"\n\x08\x63onsumer\x18\x02 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x12\n\ncreated_at\x18\x03 \x01(\x01\x12\x14\n\x0c\x64\x65livered_at\x18\x04 \x01(\t\x12\x0b\n\x03ttl\x18\x06 \x01(\x01\x12\x10\n\x08\x61ncestry\x18\x07 \x03(\t\x12\x11\n\ttask_type\x18\x08 \x01(\t\x12(\n\trecordset\x18\t \x01(\x0b\x32\x15.flwr.proto.RecordSet\x12 \n\x05\x65rror\x18\n \x01(\x0b\x32\x11.flwr.proto.Error\"\\\n\x07TaskIns\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x10\n\x08group_id\x18\x02 \x01(\t\x12\x0e\n\x06run_id\x18\x03 \x01(\x04\x12\x1e\n\x04task\x18\x04 \x01(\x0b\x32\x10.flwr.proto.Task\"\\\n\x07TaskRes\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x10\n\x08group_id\x18\x02 \x01(\t\x12\x0e\n\x06run_id\x18\x03 \x01(\x04\x12\x1e\n\x04task\x18\x04 \x01(\x0b\x32\x10.flwr.proto.Taskb\x06proto3')
|
21
21
|
|
22
22
|
_globals = globals()
|
23
23
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
@@ -25,9 +25,9 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.task_pb2', _glob
|
|
25
25
|
if _descriptor._USE_C_DESCRIPTORS == False:
|
26
26
|
DESCRIPTOR._options = None
|
27
27
|
_globals['_TASK']._serialized_start=113
|
28
|
-
_globals['_TASK']._serialized_end=
|
29
|
-
_globals['_TASKINS']._serialized_start=
|
30
|
-
_globals['_TASKINS']._serialized_end=
|
31
|
-
_globals['_TASKRES']._serialized_start=
|
32
|
-
_globals['_TASKRES']._serialized_end=
|
28
|
+
_globals['_TASK']._serialized_end=359
|
29
|
+
_globals['_TASKINS']._serialized_start=361
|
30
|
+
_globals['_TASKINS']._serialized_end=453
|
31
|
+
_globals['_TASKRES']._serialized_start=455
|
32
|
+
_globals['_TASKRES']._serialized_end=547
|
33
33
|
# @@protoc_insertion_point(module_scope)
|
flwr/proto/task_pb2.pyi
CHANGED
@@ -20,7 +20,6 @@ class Task(google.protobuf.message.Message):
|
|
20
20
|
CONSUMER_FIELD_NUMBER: builtins.int
|
21
21
|
CREATED_AT_FIELD_NUMBER: builtins.int
|
22
22
|
DELIVERED_AT_FIELD_NUMBER: builtins.int
|
23
|
-
PUSHED_AT_FIELD_NUMBER: builtins.int
|
24
23
|
TTL_FIELD_NUMBER: builtins.int
|
25
24
|
ANCESTRY_FIELD_NUMBER: builtins.int
|
26
25
|
TASK_TYPE_FIELD_NUMBER: builtins.int
|
@@ -32,7 +31,6 @@ class Task(google.protobuf.message.Message):
|
|
32
31
|
def consumer(self) -> flwr.proto.node_pb2.Node: ...
|
33
32
|
created_at: builtins.float
|
34
33
|
delivered_at: typing.Text
|
35
|
-
pushed_at: builtins.float
|
36
34
|
ttl: builtins.float
|
37
35
|
@property
|
38
36
|
def ancestry(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ...
|
@@ -47,7 +45,6 @@ class Task(google.protobuf.message.Message):
|
|
47
45
|
consumer: typing.Optional[flwr.proto.node_pb2.Node] = ...,
|
48
46
|
created_at: builtins.float = ...,
|
49
47
|
delivered_at: typing.Text = ...,
|
50
|
-
pushed_at: builtins.float = ...,
|
51
48
|
ttl: builtins.float = ...,
|
52
49
|
ancestry: typing.Optional[typing.Iterable[typing.Text]] = ...,
|
53
50
|
task_type: typing.Text = ...,
|
@@ -55,7 +52,7 @@ class Task(google.protobuf.message.Message):
|
|
55
52
|
error: typing.Optional[flwr.proto.error_pb2.Error] = ...,
|
56
53
|
) -> None: ...
|
57
54
|
def HasField(self, field_name: typing_extensions.Literal["consumer",b"consumer","error",b"error","producer",b"producer","recordset",b"recordset"]) -> builtins.bool: ...
|
58
|
-
def ClearField(self, field_name: typing_extensions.Literal["ancestry",b"ancestry","consumer",b"consumer","created_at",b"created_at","delivered_at",b"delivered_at","error",b"error","producer",b"producer","
|
55
|
+
def ClearField(self, field_name: typing_extensions.Literal["ancestry",b"ancestry","consumer",b"consumer","created_at",b"created_at","delivered_at",b"delivered_at","error",b"error","producer",b"producer","recordset",b"recordset","task_type",b"task_type","ttl",b"ttl"]) -> None: ...
|
59
56
|
global___Task = Task
|
60
57
|
|
61
58
|
class TaskIns(google.protobuf.message.Message):
|
flwr/server/app.py
CHANGED
@@ -40,7 +40,7 @@ from flwr.common.args import try_obtain_server_certificates
|
|
40
40
|
from flwr.common.auth_plugin import ExecAuthPlugin
|
41
41
|
from flwr.common.config import get_flwr_dir, parse_config_args
|
42
42
|
from flwr.common.constant import (
|
43
|
-
|
43
|
+
AUTH_TYPE_YAML_KEY,
|
44
44
|
CLIENT_OCTET,
|
45
45
|
EXEC_API_DEFAULT_SERVER_ADDRESS,
|
46
46
|
FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS,
|
@@ -265,7 +265,7 @@ def run_superlink() -> None:
|
|
265
265
|
simulationio_address, _, _ = _format_address(args.simulationio_api_address)
|
266
266
|
|
267
267
|
# Obtain certificates
|
268
|
-
certificates = try_obtain_server_certificates(args
|
268
|
+
certificates = try_obtain_server_certificates(args)
|
269
269
|
|
270
270
|
# Disable the user auth TLS check if args.disable_oidc_tls_cert_verification is
|
271
271
|
# provided
|
@@ -353,17 +353,13 @@ def run_superlink() -> None:
|
|
353
353
|
) is None:
|
354
354
|
flwr_exit(ExitCode.COMMON_MISSING_EXTRA_REST)
|
355
355
|
|
356
|
-
_, ssl_certfile, ssl_keyfile = (
|
357
|
-
certificates if certificates is not None else (None, None, None)
|
358
|
-
)
|
359
|
-
|
360
356
|
fleet_thread = threading.Thread(
|
361
357
|
target=_run_fleet_api_rest,
|
362
358
|
args=(
|
363
359
|
host,
|
364
360
|
port,
|
365
|
-
ssl_keyfile,
|
366
|
-
ssl_certfile,
|
361
|
+
args.ssl_keyfile,
|
362
|
+
args.ssl_certfile,
|
367
363
|
state_factory,
|
368
364
|
ffs_factory,
|
369
365
|
num_workers,
|
@@ -582,7 +578,7 @@ def _try_obtain_exec_auth_plugin(
|
|
582
578
|
|
583
579
|
# Load authentication configuration
|
584
580
|
auth_config: dict[str, Any] = config.get("authentication", {})
|
585
|
-
auth_type: str = auth_config.get(
|
581
|
+
auth_type: str = auth_config.get(AUTH_TYPE_YAML_KEY, "")
|
586
582
|
|
587
583
|
# Load authentication plugin
|
588
584
|
try:
|
@@ -126,7 +126,6 @@ class InMemoryDriver(Driver):
|
|
126
126
|
# Convert Message to TaskIns
|
127
127
|
taskins = message_to_taskins(msg)
|
128
128
|
# Store in state
|
129
|
-
taskins.task.pushed_at = time.time()
|
130
129
|
task_id = self.state.store_task_ins(taskins)
|
131
130
|
if task_id:
|
132
131
|
task_ids.append(str(task_id))
|
@@ -22,7 +22,7 @@ from uuid import UUID
|
|
22
22
|
|
23
23
|
import grpc
|
24
24
|
|
25
|
-
from flwr.common import ConfigsRecord
|
25
|
+
from flwr.common import ConfigsRecord
|
26
26
|
from flwr.common.constant import Status
|
27
27
|
from flwr.common.logger import log
|
28
28
|
from flwr.common.serde import (
|
@@ -151,9 +151,6 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
151
151
|
context,
|
152
152
|
)
|
153
153
|
|
154
|
-
# Set pushed_at (timestamp in seconds)
|
155
|
-
pushed_at = now().timestamp()
|
156
|
-
|
157
154
|
# Validate request and insert in State
|
158
155
|
_raise_if(
|
159
156
|
validation_error=len(request.messages_list) == 0,
|
@@ -165,7 +162,6 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
165
162
|
message_proto = request.messages_list.pop(0)
|
166
163
|
message = message_from_proto(message_proto=message_proto)
|
167
164
|
task_ins = message_to_taskins(message=message)
|
168
|
-
task_ins.task.pushed_at = pushed_at
|
169
165
|
validation_errors = validate_task_ins_or_res(task_ins)
|
170
166
|
_raise_if(
|
171
167
|
validation_error=bool(validation_errors),
|
@@ -25,6 +25,7 @@ from flwr.common import now
|
|
25
25
|
from flwr.common.constant import (
|
26
26
|
PUBLIC_KEY_HEADER,
|
27
27
|
SIGNATURE_HEADER,
|
28
|
+
SYSTEM_TIME_TOLERANCE,
|
28
29
|
TIMESTAMP_HEADER,
|
29
30
|
TIMESTAMP_TOLERANCE,
|
30
31
|
)
|
@@ -38,10 +39,15 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
38
39
|
)
|
39
40
|
from flwr.server.superlink.linkstate import LinkStateFactory
|
40
41
|
|
42
|
+
MIN_TIMESTAMP_DIFF = -SYSTEM_TIME_TOLERANCE
|
43
|
+
MAX_TIMESTAMP_DIFF = TIMESTAMP_TOLERANCE + SYSTEM_TIME_TOLERANCE
|
41
44
|
|
42
|
-
|
45
|
+
|
46
|
+
def _unary_unary_rpc_terminator(
|
47
|
+
message: str, code: Any = grpc.StatusCode.UNAUTHENTICATED
|
48
|
+
) -> grpc.RpcMethodHandler:
|
43
49
|
def terminate(_request: GrpcMessage, context: grpc.ServicerContext) -> GrpcMessage:
|
44
|
-
context.abort(
|
50
|
+
context.abort(code, message)
|
45
51
|
raise RuntimeError("Should not reach this point") # Make mypy happy
|
46
52
|
|
47
53
|
return grpc.unary_unary_rpc_method_handler(terminate)
|
@@ -64,7 +70,7 @@ class AuthenticateServerInterceptor(grpc.ServerInterceptor): # type: ignore
|
|
64
70
|
self.state_factory = state_factory
|
65
71
|
self.auto_auth = auto_auth
|
66
72
|
|
67
|
-
def intercept_service(
|
73
|
+
def intercept_service( # pylint: disable=too-many-return-statements
|
68
74
|
self,
|
69
75
|
continuation: Callable[[Any], Any],
|
70
76
|
handler_call_details: grpc.HandlerCallDetails,
|
@@ -75,6 +81,13 @@ class AuthenticateServerInterceptor(grpc.ServerInterceptor): # type: ignore
|
|
75
81
|
metadata sent by the node. Continue RPC call if node is authenticated, else,
|
76
82
|
terminate RPC call by setting context to abort.
|
77
83
|
"""
|
84
|
+
# Filter out non-Fleet service calls
|
85
|
+
if not handler_call_details.method.startswith("/flwr.proto.Fleet/"):
|
86
|
+
return _unary_unary_rpc_terminator(
|
87
|
+
"This request should be sent to a different service.",
|
88
|
+
grpc.StatusCode.FAILED_PRECONDITION,
|
89
|
+
)
|
90
|
+
|
78
91
|
state = self.state_factory.state()
|
79
92
|
metadata_dict = dict(handler_call_details.invocation_metadata)
|
80
93
|
|
@@ -100,7 +113,7 @@ class AuthenticateServerInterceptor(grpc.ServerInterceptor): # type: ignore
|
|
100
113
|
current = now()
|
101
114
|
time_diff = current - datetime.datetime.fromisoformat(timestamp_iso)
|
102
115
|
# Abort the RPC call if the timestamp is too old or in the future
|
103
|
-
if not
|
116
|
+
if not MIN_TIMESTAMP_DIFF < time_diff.total_seconds() < MAX_TIMESTAMP_DIFF:
|
104
117
|
return _unary_unary_rpc_terminator("Invalid timestamp")
|
105
118
|
|
106
119
|
# Continue the RPC call
|
@@ -15,7 +15,6 @@
|
|
15
15
|
"""Fleet API message handlers."""
|
16
16
|
|
17
17
|
|
18
|
-
import time
|
19
18
|
from typing import Optional
|
20
19
|
from uuid import UUID
|
21
20
|
|
@@ -122,9 +121,6 @@ def push_messages(
|
|
122
121
|
if abort_msg:
|
123
122
|
raise InvalidRunStatusException(abort_msg)
|
124
123
|
|
125
|
-
# Set pushed_at (timestamp in seconds)
|
126
|
-
task_res.task.pushed_at = time.time()
|
127
|
-
|
128
124
|
# Store TaskRes in State
|
129
125
|
message_id: Optional[UUID] = state.store_task_res(task_res=task_res)
|
130
126
|
|
@@ -126,7 +126,6 @@ CREATE TABLE IF NOT EXISTS task_ins(
|
|
126
126
|
consumer_node_id INTEGER,
|
127
127
|
created_at REAL,
|
128
128
|
delivered_at TEXT,
|
129
|
-
pushed_at REAL,
|
130
129
|
ttl REAL,
|
131
130
|
ancestry TEXT,
|
132
131
|
task_type TEXT,
|
@@ -144,7 +143,6 @@ CREATE TABLE IF NOT EXISTS task_res(
|
|
144
143
|
consumer_node_id INTEGER,
|
145
144
|
created_at REAL,
|
146
145
|
delivered_at TEXT,
|
147
|
-
pushed_at REAL,
|
148
146
|
ttl REAL,
|
149
147
|
ancestry TEXT,
|
150
148
|
task_type TEXT,
|
@@ -1053,7 +1051,6 @@ def task_ins_to_dict(task_msg: TaskIns) -> dict[str, Any]:
|
|
1053
1051
|
"consumer_node_id": task_msg.task.consumer.node_id,
|
1054
1052
|
"created_at": task_msg.task.created_at,
|
1055
1053
|
"delivered_at": task_msg.task.delivered_at,
|
1056
|
-
"pushed_at": task_msg.task.pushed_at,
|
1057
1054
|
"ttl": task_msg.task.ttl,
|
1058
1055
|
"ancestry": ",".join(task_msg.task.ancestry),
|
1059
1056
|
"task_type": task_msg.task.task_type,
|
@@ -1072,7 +1069,6 @@ def task_res_to_dict(task_msg: TaskRes) -> dict[str, Any]:
|
|
1072
1069
|
"consumer_node_id": task_msg.task.consumer.node_id,
|
1073
1070
|
"created_at": task_msg.task.created_at,
|
1074
1071
|
"delivered_at": task_msg.task.delivered_at,
|
1075
|
-
"pushed_at": task_msg.task.pushed_at,
|
1076
1072
|
"ttl": task_msg.task.ttl,
|
1077
1073
|
"ancestry": ",".join(task_msg.task.ancestry),
|
1078
1074
|
"task_type": task_msg.task.task_type,
|
@@ -1099,7 +1095,6 @@ def dict_to_task_ins(task_dict: dict[str, Any]) -> TaskIns:
|
|
1099
1095
|
),
|
1100
1096
|
created_at=task_dict["created_at"],
|
1101
1097
|
delivered_at=task_dict["delivered_at"],
|
1102
|
-
pushed_at=task_dict["pushed_at"],
|
1103
1098
|
ttl=task_dict["ttl"],
|
1104
1099
|
ancestry=task_dict["ancestry"].split(","),
|
1105
1100
|
task_type=task_dict["task_type"],
|
@@ -1127,7 +1122,6 @@ def dict_to_task_res(task_dict: dict[str, Any]) -> TaskRes:
|
|
1127
1122
|
),
|
1128
1123
|
created_at=task_dict["created_at"],
|
1129
1124
|
delivered_at=task_dict["delivered_at"],
|
1130
|
-
pushed_at=task_dict["pushed_at"],
|
1131
1125
|
ttl=task_dict["ttl"],
|
1132
1126
|
ancestry=task_dict["ancestry"].split(","),
|
1133
1127
|
task_type=task_dict["task_type"],
|
flwr/server/utils/validator.py
CHANGED
@@ -45,9 +45,6 @@ def validate_task_ins_or_res(tasks_ins_res: Union[TaskIns, TaskRes]) -> list[str
|
|
45
45
|
validation_errors.append("`delivered_at` must be an empty str")
|
46
46
|
if tasks_ins_res.task.ttl <= 0:
|
47
47
|
validation_errors.append("`ttl` must be higher than zero")
|
48
|
-
if tasks_ins_res.task.pushed_at < 1711497600.0:
|
49
|
-
# unix timestamp of 27 March 2024 00h:00m:00s UTC
|
50
|
-
validation_errors.append("`pushed_at` is not a recent timestamp")
|
51
48
|
|
52
49
|
# Verify TTL and created_at time
|
53
50
|
current_time = time.time()
|
{flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.15.
|
3
|
+
Version: 1.15.2.dev20250215
|
4
4
|
Summary: Flower: A Friendly Federated AI Framework
|
5
5
|
Home-page: https://flower.ai
|
6
6
|
License: Apache-2.0
|
@@ -40,7 +40,7 @@ Requires-Dist: pathspec (>=0.12.1,<0.13.0)
|
|
40
40
|
Requires-Dist: protobuf (>=4.21.6,<5.0.0)
|
41
41
|
Requires-Dist: pycryptodome (>=3.18.0,<4.0.0)
|
42
42
|
Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
|
43
|
-
Requires-Dist: ray (==2.
|
43
|
+
Requires-Dist: ray (==2.31.0) ; (python_version >= "3.9" and python_version < "3.13") and (extra == "simulation")
|
44
44
|
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
45
45
|
Requires-Dist: rich (>=13.5.0,<14.0.0)
|
46
46
|
Requires-Dist: starlette (>=0.45.2,<0.46.0) ; extra == "rest"
|
{flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/RECORD
RENAMED
@@ -2,7 +2,7 @@ flwr/__init__.py,sha256=VmBWedrCxqmt4QvUHBLqyVEH6p7zaFMD_oCHerXHSVw,937
|
|
2
2
|
flwr/cli/__init__.py,sha256=cZJVgozlkC6Ni2Hd_FAIrqefrkCGOV18fikToq-6iLw,720
|
3
3
|
flwr/cli/app.py,sha256=UeXrW5gxrUnFViDjAMIxGNZZKwu3a1oAj83v53IWIWM,1382
|
4
4
|
flwr/cli/auth_plugin/__init__.py,sha256=FyaoqPzcxlBTFfJ2sBRC5USwQLmAhFr5KuBwfMO4bmo,1052
|
5
|
-
flwr/cli/auth_plugin/oidc_cli_plugin.py,sha256=
|
5
|
+
flwr/cli/auth_plugin/oidc_cli_plugin.py,sha256=gIhW6Jg9QAo-jL43LYPpw_kn7pdUZZae0s0H8dEgjLM,5384
|
6
6
|
flwr/cli/build.py,sha256=4P70i_FnUs0P21aTwjTXtFQSAfY-C04hUDF-2npfJdo,6345
|
7
7
|
flwr/cli/cli_user_auth_interceptor.py,sha256=aZepPA298s-HjGmkJGMvI_uZe72O5aLC3jri-ilG53o,3126
|
8
8
|
flwr/cli/config_utils.py,sha256=LelRR960I36n1IPw7BIu79fKoOh0JePA58kAtoXSTH0,7518
|
@@ -12,15 +12,15 @@ flwr/cli/install.py,sha256=-RnrYGejN_zyXXp_CoddSQwoQfRTWWyt9WYlxphJzyU,8180
|
|
12
12
|
flwr/cli/log.py,sha256=vcO-r5EIc127mOQ26uxKVITX-w_Zib7AxSVuuN70_JY,6671
|
13
13
|
flwr/cli/login/__init__.py,sha256=6_9zOzbPOAH72K2wX3-9dXTAbS7Mjpa5sEn2lA6eHHI,800
|
14
14
|
flwr/cli/login/login.py,sha256=iNnNF1bvV0n8Z-vNc89azFNA73JqKZlO1s5OF2atsTc,3917
|
15
|
-
flwr/cli/ls.py,sha256=
|
15
|
+
flwr/cli/ls.py,sha256=cm3NuY1sFq51xVRhUG0MbAfVTrRSjJ1HMIubde80LuY,11433
|
16
16
|
flwr/cli/new/__init__.py,sha256=pOQtPT9W4kCIttcKne5m-FtJbvTqdjTVJxzQ9AUYK8I,790
|
17
17
|
flwr/cli/new/new.py,sha256=scyyKt8mzkc3El1bypgkHjKwVQEc2-q4I50PxriPFdI,9922
|
18
18
|
flwr/cli/new/templates/__init__.py,sha256=4luU8RL-CK8JJCstQ_ON809W9bNTkY1l9zSaPKBkgwY,725
|
19
19
|
flwr/cli/new/templates/app/.gitignore.tpl,sha256=HZJcGQoxp7aUzaPg8Uqch3kNrIESwr9yjimDxJYgXVY,3104
|
20
20
|
flwr/cli/new/templates/app/LICENSE.tpl,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
21
|
-
flwr/cli/new/templates/app/README.baseline.md.tpl,sha256=
|
21
|
+
flwr/cli/new/templates/app/README.baseline.md.tpl,sha256=oClo5eR0iLuPzBT7uS3ikhNRAnySz_lhkHFElixKyJM,9640
|
22
22
|
flwr/cli/new/templates/app/README.flowertune.md.tpl,sha256=QSG51uifue2KVZz2ZNw8kmOStS7svC2AQ2gTa5E7Bhs,3326
|
23
|
-
flwr/cli/new/templates/app/README.md.tpl,sha256=
|
23
|
+
flwr/cli/new/templates/app/README.md.tpl,sha256=qZ6XHeCdSoDwtJqgcyi-ChgOCLMwQ3E42rcY-9qhlUY,1392
|
24
24
|
flwr/cli/new/templates/app/__init__.py,sha256=DU7QMY7IhMQyuwm_tja66xU0KXTWQFqzfTqwg-_NJdE,729
|
25
25
|
flwr/cli/new/templates/app/code/__init__.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
26
26
|
flwr/cli/new/templates/app/code/__init__.py,sha256=EM6vfvgAILKPaPn7H1wMV1Wi01WyZCP_Eg6NxD6oWg8,736
|
@@ -58,19 +58,19 @@ flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=XlJqA4Ix_PloO_zJLhjiN
|
|
58
58
|
flwr/cli/new/templates/app/code/task.sklearn.py.tpl,sha256=SeIIo0rr_6ffn4Qx2xELD18jYXCkcW__NWtYEDXCICM,1843
|
59
59
|
flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=SKXAZdgBnPpbAbJ90Rb7oQ5ilnopBx_j_JNFoUDeEAI,1732
|
60
60
|
flwr/cli/new/templates/app/code/utils.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
61
|
-
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=
|
62
|
-
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=
|
63
|
-
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256
|
64
|
-
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=
|
65
|
-
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=
|
66
|
-
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=
|
67
|
-
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=
|
68
|
-
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=
|
69
|
-
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=
|
61
|
+
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=KaRdKS6Um_7_BwaC2JyPVssvO0XoqugXr3uScQW_gmQ,2666
|
62
|
+
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=V0ARllDsjHQU7PkgsPk2wQKmcWkbiTYNnDzrQaH8PX8,1873
|
63
|
+
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=-br1AywMPM2TdOKwooz_jotI4iUoqLMmDkdVIV5txYM,1143
|
64
|
+
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=p8v65ymJtY50uh8kSyzAOYN34mvf2oQti2yN8d4T_gM,673
|
65
|
+
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=faz_lde3WU4HAJK_3h2SDR8Kejsv9P1jUHQQKyKdyZM,744
|
66
|
+
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=xP-U8w8_qim3BS5pTa9QYj38H2DfdcY24mKOdZRqkus,611
|
67
|
+
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=wLYfJlglT6k3Q5t3PGC43H5eVNouDnEqwK19KHUEj8o,710
|
68
|
+
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=9p0NzvIHoM0ZvlDUpa1lBMwIY_kpigmNCM7-5r3xWcg,686
|
69
|
+
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=C_kmVlZ-kqzcBJfMzsimE0voz1UbJMQqO_hfZQjMmg0,710
|
70
70
|
flwr/cli/run/__init__.py,sha256=cCsKVB0SFzh2b3QmGba6BHckB85xlhjh3mh4pBpACtY,790
|
71
71
|
flwr/cli/run/run.py,sha256=kEOYKin9qPJy8SODxcAvIWk-OskKPsxvcbvhDhf2VD4,8299
|
72
|
-
flwr/cli/stop.py,sha256=
|
73
|
-
flwr/cli/utils.py,sha256=
|
72
|
+
flwr/cli/stop.py,sha256=E4TGynmYQss5iWJ_fjSdYIW8nrNta2KOiK4sfvHKO_g,4976
|
73
|
+
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
|
@@ -109,15 +109,15 @@ flwr/client/rest_client/__init__.py,sha256=5KGlp7pjc1dhNRkKlaNtUfQmg8wrRFh9lS3P3
|
|
109
109
|
flwr/client/rest_client/connection.py,sha256=9_JDGHkmaiPgk6CmcQId56Ia1ucQfrqcpNOUObdZaZU,13008
|
110
110
|
flwr/client/run_info_store.py,sha256=ZN2Phi4DSLbSyzg8RmzJcVYh1g6eurHOmWRCT7GMtw4,4040
|
111
111
|
flwr/client/supernode/__init__.py,sha256=SUhWOzcgXRNXk1V9UgB5-FaWukqqrOEajVUHEcPkwyQ,865
|
112
|
-
flwr/client/supernode/app.py,sha256=
|
112
|
+
flwr/client/supernode/app.py,sha256=oBbggh56HoieksBkTdDHAJC8VUFbrmGOP0-D9wdcZek,9265
|
113
113
|
flwr/client/typing.py,sha256=dxoTBnTMfqXr5J7G3y-uNjqxYCddvxhu89spfj4Lm2U,1048
|
114
114
|
flwr/common/__init__.py,sha256=TVaoFEJE158aui1TPZQiJCDZX4RNHRyI8I55VC80HhI,3901
|
115
115
|
flwr/common/address.py,sha256=9KNYE69WW_QVcyumsux3Qn1wmn4J7f13Y9nHASpvzbA,3018
|
116
|
-
flwr/common/args.py,sha256=
|
116
|
+
flwr/common/args.py,sha256=MgkTUXACuySHyNdxrb7-pK0_R-S2Q7W5MnE3onYUf5I,5183
|
117
117
|
flwr/common/auth_plugin/__init__.py,sha256=1Y8Oj3iB49IHDu9tvDih1J74Ygu7k85V9s2A4WORPyA,887
|
118
118
|
flwr/common/auth_plugin/auth_plugin.py,sha256=wgDorBUB4IkK6twQ8vNawRVz7BDPmKdXZBNLqhU9RSs,3871
|
119
|
-
flwr/common/config.py,sha256=
|
120
|
-
flwr/common/constant.py,sha256=
|
119
|
+
flwr/common/config.py,sha256=SAkG3BztnA6iupXxF3GAIpGmWVVCH0ptyMpC9yjr_14,13965
|
120
|
+
flwr/common/constant.py,sha256=AdNCrHi4sgMCecdX7hHWxMFz3y9pWsjSGU25mA4OJyE,6619
|
121
121
|
flwr/common/context.py,sha256=uJ-mnoC_8y_udEb3kAX-r8CPphNTWM72z1AlsvQEu54,2403
|
122
122
|
flwr/common/date.py,sha256=NHHpESce5wYqEwoDXf09gp9U9l_5Bmlh2BsOcwS-kDM,1554
|
123
123
|
flwr/common/differential_privacy.py,sha256=YA01NqjddKNAEVmf7hXmOVxOjhekgzvJudk3mBGq-2k,6148
|
@@ -126,11 +126,11 @@ flwr/common/dp.py,sha256=vddkvyjV2FhRoN4VuU2LeAM1UBn7dQB8_W-Qdiveal8,1978
|
|
126
126
|
flwr/common/exit/__init__.py,sha256=-ZOJYLaNnR729a7VzZiFsLiqngzKQh3xc27svYStZ_Q,826
|
127
127
|
flwr/common/exit/exit.py,sha256=DmZFyksp-w1sFDQekq5Z-qfnr-ivCAv78aQkqj-TDps,3458
|
128
128
|
flwr/common/exit/exit_code.py,sha256=PNEnCrZfOILjfDAFu5m-2YWEJBrk97xglq4zCUlqV7E,3470
|
129
|
-
flwr/common/exit_handlers.py,sha256=
|
129
|
+
flwr/common/exit_handlers.py,sha256=yclujry30954o0lI7vtknTajskPCvK8TXw2V3RdldXU,3174
|
130
130
|
flwr/common/grpc.py,sha256=K60AIvIqH0CvkkiqBfw5HoxQfbFOL2DrhKPjbZ8raIE,9786
|
131
131
|
flwr/common/logger.py,sha256=Hund1C6bEhMw3GemlzuFK22tXZ27YeHLrFB0b4LP5f8,13041
|
132
132
|
flwr/common/message.py,sha256=Zv4ID2BLQsbff0F03DI_MeFoHbSqVZAdDD9NcKYv6Zo,13832
|
133
|
-
flwr/common/object_ref.py,sha256=
|
133
|
+
flwr/common/object_ref.py,sha256=Mv8OE6f9wmLs_KQWt8aPV5aw-g6fgWDfj28L2b8Jl-Y,9514
|
134
134
|
flwr/common/parameter.py,sha256=-bFAUayToYDF50FZGrBC1hQYJCQDtB2bbr3ZuVLMtdE,2095
|
135
135
|
flwr/common/pyproject.py,sha256=vEAxl800XiJ1JNJDui8vuVV-08msnB6hLt7o95viZl0,1386
|
136
136
|
flwr/common/record/__init__.py,sha256=LUixpq0Z-lMJwCIu1-4u5HfvRPjRMRgoAc6YJQ6UEOs,1055
|
@@ -207,8 +207,8 @@ flwr/proto/simulationio_pb2.py,sha256=GOOmivAJPLQ6mPXrfKS8CyYeE6Kk-Q5mInLz5pyZSs
|
|
207
207
|
flwr/proto/simulationio_pb2.pyi,sha256=oXx8_FLBe5B54wduZj-f89kub73XxNtQbThuW8YfPAs,2660
|
208
208
|
flwr/proto/simulationio_pb2_grpc.py,sha256=9I3yAfJaeMuG-qH_5Ge45eFOftsIOmL9b8E_xHmcvKw,11232
|
209
209
|
flwr/proto/simulationio_pb2_grpc.pyi,sha256=YHvKtyo7UdbBgdhoN0ndzZeB5vIC3JuR5PAJLrl-OKM,3206
|
210
|
-
flwr/proto/task_pb2.py,sha256=
|
211
|
-
flwr/proto/task_pb2.pyi,sha256=
|
210
|
+
flwr/proto/task_pb2.py,sha256=pFKpq2QSvmFQOEpv2bgCG9jPAVauIHXQ9p5ASW-Z6lE,2322
|
211
|
+
flwr/proto/task_pb2.pyi,sha256=PZXt-QkD-hFzTlgNVVx6SGvgbTCweBfisivEi_HfDWc,4183
|
212
212
|
flwr/proto/task_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
213
213
|
flwr/proto/task_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
|
214
214
|
flwr/proto/transport_pb2.py,sha256=P-jX_tUyk_8xFe-vIUUSfZlHGtk2Ou3A8eXdBKkp5AY,9824
|
@@ -217,7 +217,7 @@ flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPc
|
|
217
217
|
flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
|
218
218
|
flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
219
219
|
flwr/server/__init__.py,sha256=cEg1oecBu4cKB69iJCqWEylC8b5XW47bl7rQiJsdTvM,1528
|
220
|
-
flwr/server/app.py,sha256=
|
220
|
+
flwr/server/app.py,sha256=CVj7lDAYJ4GYnBvAIa0R3A8JV5Dt-ATxDOrLxafLFV8,30545
|
221
221
|
flwr/server/client_manager.py,sha256=7Ese0tgrH-i-ms363feYZJKwB8gWnXSmg_hYF2Bju4U,6227
|
222
222
|
flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
|
223
223
|
flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
|
@@ -229,7 +229,7 @@ flwr/server/criterion.py,sha256=ypbAexbztzGUxNen9RCHF91QeqiEQix4t4Ih3E-42MM,1061
|
|
229
229
|
flwr/server/driver/__init__.py,sha256=bikRv6CjTwSvYh7tf10gziU5o2YotOWhhftz2tr3KDc,886
|
230
230
|
flwr/server/driver/driver.py,sha256=u_fMfqLYTroTafGCNwKPHI4lttRL-Z5CqeT3_FHSq-Q,5701
|
231
231
|
flwr/server/driver/grpc_driver.py,sha256=3mSws0l83fWD4aq9-MmHFnIfyf4REoAXUkWfyJDHros,9864
|
232
|
-
flwr/server/driver/inmemory_driver.py,sha256=
|
232
|
+
flwr/server/driver/inmemory_driver.py,sha256=7ZtWDDJa8xupPAHNaDdCE2DOIOIYgrffmJMdKjs3wdA,6616
|
233
233
|
flwr/server/history.py,sha256=qSb5_pPTrwofpSYGsZWzMPkl_4uJ4mJFWesxXDrEvDU,5026
|
234
234
|
flwr/server/run_serverapp.py,sha256=vIPhvJx0i5sEZO4IKM6ruCXmx4ncat76rh0B4KhdhhM,2446
|
235
235
|
flwr/server/server.py,sha256=1ZsFEptmAV-L2vP2etNC9Ed5CLSxpuKzUFkAPQ4l5Xc,17893
|
@@ -265,7 +265,7 @@ flwr/server/strategy/strategy.py,sha256=cXapkD5uDrt5C-RbmWDn9FLoap3Q41i7GKvbmfbC
|
|
265
265
|
flwr/server/superlink/__init__.py,sha256=8tHYCfodUlRD8PCP9fHgvu8cz5N31A2QoRVL0jDJ15E,707
|
266
266
|
flwr/server/superlink/driver/__init__.py,sha256=5soEK5QSvxNjmJQ-CGTWROc4alSAeU0e9Ad9RDhsd3E,717
|
267
267
|
flwr/server/superlink/driver/serverappio_grpc.py,sha256=UzHwo6qYZMeOhr7nn1iZbcyDSmwvnq_kpYH0mEAndW0,2173
|
268
|
-
flwr/server/superlink/driver/serverappio_servicer.py,sha256=
|
268
|
+
flwr/server/superlink/driver/serverappio_servicer.py,sha256=Ld_d4ygbvJ7YmsIA8O9oD3E4tBKDY7MlpQzBjDUyvi0,13116
|
269
269
|
flwr/server/superlink/ffs/__init__.py,sha256=FAY-zShcfPmOxosok2QyT6hTNMNctG8cH9s_nIl8jkI,840
|
270
270
|
flwr/server/superlink/ffs/disk_ffs.py,sha256=n_Ah0sQwXGVQ9wj5965nLjdkQQbpoHCljjXKFnwftsU,3297
|
271
271
|
flwr/server/superlink/ffs/ffs.py,sha256=qLI1UfosJugu2BKOJWqHIhafTm-YiuKqGf3OGWPH0NM,2395
|
@@ -280,21 +280,21 @@ flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py,sha256=h3EhqgelegVC4E
|
|
280
280
|
flwr/server/superlink/fleet/grpc_bidi/grpc_server.py,sha256=mxPxyEF0IW0vV41Bqk1zfKOdRDEvXPwzJyMiRMg7nTI,5173
|
281
281
|
flwr/server/superlink/fleet/grpc_rere/__init__.py,sha256=j2hyC342am-_Hgp1g80Y3fGDzfTI6n8QOOn2PyWf4eg,758
|
282
282
|
flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=syWWZgsU3PHvIuvSoJxUTbEdkOtyV6psXAbRowNE_yY,5533
|
283
|
-
flwr/server/superlink/fleet/grpc_rere/server_interceptor.py,sha256=
|
283
|
+
flwr/server/superlink/fleet/grpc_rere/server_interceptor.py,sha256=KPgAcnYsKPPI7_iYNSnqGbyv4tsqZuBqrTiREwVBJiM,6984
|
284
284
|
flwr/server/superlink/fleet/message_handler/__init__.py,sha256=h8oLD7uo5lKICPy0rRdKRjTYe62u8PKkT_fA4xF5JPA,731
|
285
|
-
flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=
|
285
|
+
flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=QpLo3E-viPQ1Ia4isRM21htCfU3QH0P4wqMfXAtX8Hk,5412
|
286
286
|
flwr/server/superlink/fleet/rest_rere/__init__.py,sha256=5jbYbAn75sGv-gBwOPDySE0kz96F6dTYLeMrGqNi4lM,735
|
287
287
|
flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=L7sg9Uyp7l1bViYNWjnpaDvcG_j7FYKWC1XL-8bMpsg,6710
|
288
288
|
flwr/server/superlink/fleet/vce/__init__.py,sha256=TZJsKTpYO_djv2EXx9Ji62I8TA0JiZF8jvRyJRZkAes,784
|
289
289
|
flwr/server/superlink/fleet/vce/backend/__init__.py,sha256=cGgal5qpd0_MwEdIqjJbHHSIgGa6GSPoI5_byUwtG_k,1437
|
290
290
|
flwr/server/superlink/fleet/vce/backend/backend.py,sha256=LBAQxnbfPAphVOVIvYMj0QIvVP5O-RQxKQlUGNUj974,2194
|
291
291
|
flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=jsUkFEVQTnrucK1jNQ_cUM8YwL7W4MQNA1GAf8ibRdg,7156
|
292
|
-
flwr/server/superlink/fleet/vce/vce_api.py,sha256=
|
292
|
+
flwr/server/superlink/fleet/vce/vce_api.py,sha256=iXNSAJ7f8Sg1hOrVuRTGRkLdSWeFIpNWbusoOTc4I8I,12971
|
293
293
|
flwr/server/superlink/linkstate/__init__.py,sha256=v-2JyJlCB3qyhMNwMjmcNVOq4rkooqFU0LHH8Zo1jls,1064
|
294
294
|
flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=4ahMj7TLe-GO2ctyeZ2BBRkviGv27s6x1NS_ETRJHP8,20514
|
295
295
|
flwr/server/superlink/linkstate/linkstate.py,sha256=LWA5zRwN829GDAeSo5kmkzsMu0SkXa9qg4aG_0QN0uk,12159
|
296
296
|
flwr/server/superlink/linkstate/linkstate_factory.py,sha256=ISSMjDlwuN7swxjOeYlTNpI_kuZ8PGkMcJnf1dbhUSE,2069
|
297
|
-
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=
|
297
|
+
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=YEXk_3avSF9T9sk5xxYwNeljLZ-qzg1zIAJOlkkmsX0,40146
|
298
298
|
flwr/server/superlink/linkstate/utils.py,sha256=EpRehwI4NeEW3oINICPWP9STK49N0aszd5s5jtle7DQ,13602
|
299
299
|
flwr/server/superlink/simulation/__init__.py,sha256=mg-oapC9dkzEfjXPQFior5lpWj4g9kwbLovptyYM_g0,718
|
300
300
|
flwr/server/superlink/simulation/simulationio_grpc.py,sha256=8aUrZZLdvprKUfLLqFID4aItus9beU6m1qLQYIPB7k0,2224
|
@@ -303,7 +303,7 @@ flwr/server/superlink/utils.py,sha256=KVb3K_g2vYfu9TnftcN0ewmev133WZcjuEePMm8d7G
|
|
303
303
|
flwr/server/typing.py,sha256=5kaRLZuxTEse9A0g7aVna2VhYxU3wTq1f3d3mtw7kXs,1019
|
304
304
|
flwr/server/utils/__init__.py,sha256=pltsPHJoXmUIr3utjwwYxu7_ZAGy5u4MVHzv9iA5Un8,908
|
305
305
|
flwr/server/utils/tensorboard.py,sha256=gEBD8w_5uaIfp5aw5RYH66lYZpd_SfkObHQ7eDd9MUk,5466
|
306
|
-
flwr/server/utils/validator.py,sha256=
|
306
|
+
flwr/server/utils/validator.py,sha256=BQ56tDrrOOG52q3RVeeCODz-oEBxu4L19wbfkBPdCqw,4419
|
307
307
|
flwr/server/workflow/__init__.py,sha256=SXY0XkwbkezFBxxrFB5hKUtmtAgnYISBkPouR1V71ss,902
|
308
308
|
flwr/server/workflow/constant.py,sha256=q4DLdR8Krlxuewq2AQjwTL75hphxE5ODNz4AhViHMXk,1082
|
309
309
|
flwr/server/workflow/default_workflows.py,sha256=UMC9JgdomKwxql5G0OV4AeRXWI-bMClaLAOn5OrZMnw,14073
|
@@ -327,8 +327,8 @@ flwr/superexec/exec_servicer.py,sha256=X10ILT-AoGMrB3IgI2mBe9i-QcIVUAl9bucuqVOPY
|
|
327
327
|
flwr/superexec/exec_user_auth_interceptor.py,sha256=K06OU-l4LnYhTDg071hGJuOaQWEJbZsYi5qxUmmtiG0,3704
|
328
328
|
flwr/superexec/executor.py,sha256=_B55WW2TD1fBINpabSSDRenVHXYmvlfhv-k8hJKU4lQ,3115
|
329
329
|
flwr/superexec/simulation.py,sha256=WQDon15oqpMopAZnwRZoTICYCfHqtkvFSqiTQ2hLD_g,4088
|
330
|
-
flwr_nightly-1.15.
|
331
|
-
flwr_nightly-1.15.
|
332
|
-
flwr_nightly-1.15.
|
333
|
-
flwr_nightly-1.15.
|
334
|
-
flwr_nightly-1.15.
|
330
|
+
flwr_nightly-1.15.2.dev20250215.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
331
|
+
flwr_nightly-1.15.2.dev20250215.dist-info/METADATA,sha256=-Nd-2GYUWwZLoelM8bZELVx6-p8_FLlnn-LI-sStEiI,15873
|
332
|
+
flwr_nightly-1.15.2.dev20250215.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
333
|
+
flwr_nightly-1.15.2.dev20250215.dist-info/entry_points.txt,sha256=JlNxX3qhaV18_2yj5a3kJW1ESxm31cal9iS_N_pf1Rk,538
|
334
|
+
flwr_nightly-1.15.2.dev20250215.dist-info/RECORD,,
|
{flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/LICENSE
RENAMED
File without changes
|
{flwr_nightly-1.15.0.dev20250130.dist-info → flwr_nightly-1.15.2.dev20250215.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|