flwr-nightly 1.19.0.dev20250612__py3-none-any.whl → 1.19.0.dev20250616__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/ls.py CHANGED
@@ -130,23 +130,16 @@ def ls( # pylint: disable=too-many-locals, too-many-branches, R0913, R0917
130
130
  # Display information about a specific run ID
131
131
  if run_id is not None:
132
132
  typer.echo(f"🔍 Displaying information for run ID {run_id}...")
133
- restore_output()
134
- _display_one_run(stub, run_id, output_format)
133
+ formatted_runs = _display_one_run(stub, run_id)
135
134
  # By default, list all runs
136
135
  else:
137
136
  typer.echo("📄 Listing all runs...")
138
- restore_output()
139
- _list_runs(stub, output_format)
140
-
141
- except ValueError as err:
142
- if suppress_output:
143
- redirect_output(captured_output)
144
- typer.secho(
145
- f"❌ {err}",
146
- fg=typer.colors.RED,
147
- bold=True,
148
- )
149
- raise typer.Exit(code=1) from err
137
+ formatted_runs = _list_runs(stub)
138
+ restore_output()
139
+ if output_format == CliOutputFormat.JSON:
140
+ Console().print_json(_to_json(formatted_runs))
141
+ else:
142
+ Console().print(_to_table(formatted_runs))
150
143
  finally:
151
144
  if channel:
152
145
  channel.close()
@@ -300,37 +293,23 @@ def _to_json(run_list: list[_RunListType]) -> str:
300
293
  return json.dumps({"success": True, "runs": runs_list})
301
294
 
302
295
 
303
- def _list_runs(
304
- stub: ExecStub,
305
- output_format: str = CliOutputFormat.DEFAULT,
306
- ) -> None:
296
+ def _list_runs(stub: ExecStub) -> list[_RunListType]:
307
297
  """List all runs."""
308
298
  with flwr_cli_grpc_exc_handler():
309
299
  res: ListRunsResponse = stub.ListRuns(ListRunsRequest())
310
300
  run_dict = {run_id: run_from_proto(proto) for run_id, proto in res.run_dict.items()}
311
301
 
312
- formatted_runs = _format_runs(run_dict, res.now)
313
- if output_format == CliOutputFormat.JSON:
314
- Console().print_json(_to_json(formatted_runs))
315
- else:
316
- Console().print(_to_table(formatted_runs))
302
+ return _format_runs(run_dict, res.now)
317
303
 
318
304
 
319
- def _display_one_run(
320
- stub: ExecStub,
321
- run_id: int,
322
- output_format: str = CliOutputFormat.DEFAULT,
323
- ) -> None:
305
+ def _display_one_run(stub: ExecStub, run_id: int) -> list[_RunListType]:
324
306
  """Display information about a specific run."""
325
307
  with flwr_cli_grpc_exc_handler():
326
308
  res: ListRunsResponse = stub.ListRuns(ListRunsRequest(run_id=run_id))
327
309
  if not res.run_dict:
310
+ # This won't be reached as an gRPC error is raised if run_id is invalid
328
311
  raise ValueError(f"Run ID {run_id} not found")
329
312
 
330
313
  run_dict = {run_id: run_from_proto(proto) for run_id, proto in res.run_dict.items()}
331
314
 
332
- formatted_runs = _format_runs(run_dict, res.now)
333
- if output_format == CliOutputFormat.JSON:
334
- Console().print_json(_to_json(formatted_runs))
335
- else:
336
- Console().print(_to_table(formatted_runs))
315
+ return _format_runs(run_dict, res.now)
flwr/cli/utils.py CHANGED
@@ -28,7 +28,12 @@ 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 AUTH_TYPE_JSON_KEY, CREDENTIALS_DIR, FLWR_DIR
31
+ from flwr.common.constant import (
32
+ AUTH_TYPE_JSON_KEY,
33
+ CREDENTIALS_DIR,
34
+ FLWR_DIR,
35
+ RUN_ID_NOT_FOUND_MESSAGE,
36
+ )
32
37
  from flwr.common.grpc import (
33
38
  GRPC_MAX_MESSAGE_LENGTH,
34
39
  create_channel,
@@ -320,5 +325,17 @@ def flwr_cli_grpc_exc_handler() -> Iterator[None]:
320
325
  fg=typer.colors.RED,
321
326
  bold=True,
322
327
  )
328
+ # pylint: disable=E1101
329
+ typer.secho(e.details(), fg=typer.colors.RED, bold=True)
330
+ raise typer.Exit(code=1) from None
331
+ if (
332
+ e.code() == grpc.StatusCode.NOT_FOUND
333
+ and e.details() == RUN_ID_NOT_FOUND_MESSAGE
334
+ ):
335
+ typer.secho(
336
+ "❌ Run ID not found.",
337
+ fg=typer.colors.RED,
338
+ bold=True,
339
+ )
323
340
  raise typer.Exit(code=1) from None
324
341
  raise
flwr/common/constant.py CHANGED
@@ -150,6 +150,10 @@ PULL_INITIAL_BACKOFF = 1 # Initial backoff time for pulling objects
150
150
  PULL_BACKOFF_CAP = 10 # Maximum backoff time for pulling objects
151
151
 
152
152
 
153
+ # ExecServicer constants
154
+ RUN_ID_NOT_FOUND_MESSAGE = "Run ID not found"
155
+
156
+
153
157
  class MessageType:
154
158
  """Message type."""
155
159
 
flwr/server/app.py CHANGED
@@ -91,7 +91,6 @@ P = TypeVar("P", ExecAuthPlugin, ExecAuthzPlugin)
91
91
  try:
92
92
  from flwr.ee import (
93
93
  add_ee_args_superlink,
94
- get_dashboard_server,
95
94
  get_exec_auth_plugins,
96
95
  get_exec_authz_plugins,
97
96
  get_exec_event_log_writer_plugins,
@@ -178,6 +177,7 @@ def run_superlink() -> None:
178
177
  address=exec_address,
179
178
  state_factory=state_factory,
180
179
  ffs_factory=ffs_factory,
180
+ objectstore_factory=objectstore_factory,
181
181
  executor=executor,
182
182
  certificates=certificates,
183
183
  config=parse_config_args(
@@ -332,17 +332,6 @@ def run_superlink() -> None:
332
332
  scheduler_th.start()
333
333
  bckg_threads.append(scheduler_th)
334
334
 
335
- # Add Dashboard server if available
336
- if dashboard_address := getattr(args, "dashboard_address", None):
337
- dashboard_address_str, _, _ = _format_address(dashboard_address)
338
- dashboard_server = get_dashboard_server(
339
- address=dashboard_address_str,
340
- state_factory=state_factory,
341
- certificates=None,
342
- )
343
-
344
- grpc_servers.append(dashboard_server)
345
-
346
335
  # Graceful shutdown
347
336
  register_exit_handlers(
348
337
  event_type=EventType.RUN_SUPERLINK_LEAVE,
@@ -249,7 +249,9 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
249
249
  inquired_in_message_ids=message_ids,
250
250
  found_in_message_dict=self.message_ins_store,
251
251
  node_id_to_online_until={
252
- node_id: self.node_ids[node_id][0] for node_id in dst_node_ids
252
+ node_id: self.node_ids[node_id][0]
253
+ for node_id in dst_node_ids
254
+ if node_id in self.node_ids
253
255
  },
254
256
  current_time=current,
255
257
  )
@@ -478,7 +480,9 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
478
480
  if they have not sent a heartbeat before `active_until`.
479
481
  """
480
482
  current = now()
481
- for record in [self.run_ids[run_id] for run_id in run_ids]:
483
+ for record in (self.run_ids.get(run_id) for run_id in run_ids):
484
+ if record is None:
485
+ continue
482
486
  with record.lock:
483
487
  if record.run.status.status in (Status.STARTING, Status.RUNNING):
484
488
  if record.active_until < current.timestamp():
@@ -25,7 +25,7 @@ from flwr.common import Message
25
25
  from flwr.common.constant import SUPERLINK_NODE_ID, Status
26
26
  from flwr.common.inflatable import (
27
27
  UnexpectedObjectContentError,
28
- get_descendant_object_ids,
28
+ get_all_nested_objects,
29
29
  get_object_tree,
30
30
  no_object_id_recompute,
31
31
  )
@@ -181,7 +181,7 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
181
181
  objects_to_push=objects_to_push,
182
182
  )
183
183
 
184
- def PullMessages(
184
+ def PullMessages( # pylint: disable=R0914
185
185
  self, request: PullResMessagesRequest, context: grpc.ServicerContext
186
186
  ) -> PullResMessagesResponse:
187
187
  """Pull a set of Messages."""
@@ -209,14 +209,18 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
209
209
  for msg_res in messages_res:
210
210
  if msg_res.metadata.src_node_id == SUPERLINK_NODE_ID:
211
211
  with no_object_id_recompute():
212
- descendants = list(get_descendant_object_ids(msg_res))
212
+ all_objects = get_all_nested_objects(msg_res)
213
+ descendants = list(all_objects.keys())[:-1]
213
214
  message_obj_id = msg_res.metadata.message_id
214
- # Store mapping
215
- store.set_message_descendant_ids(
216
- msg_object_id=message_obj_id, descendant_ids=descendants
217
- )
218
- # Preregister
219
- store.preregister(request.run_id, get_object_tree(msg_res))
215
+ # Store mapping
216
+ store.set_message_descendant_ids(
217
+ msg_object_id=message_obj_id, descendant_ids=descendants
218
+ )
219
+ # Preregister
220
+ store.preregister(request.run_id, get_object_tree(msg_res))
221
+ # Store objects
222
+ for obj_id, obj in all_objects.items():
223
+ store.put(obj_id, obj.deflate())
220
224
 
221
225
  # Delete the instruction Messages and their replies if found
222
226
  message_ins_ids_to_delete = {
@@ -243,10 +247,8 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
243
247
  try:
244
248
  msg_object_id = msg.metadata.message_id
245
249
  descendants = store.get_message_descendant_ids(msg_object_id)
246
- # Include the object_id of the message itself
247
- objects_to_pull[msg_object_id] = ObjectIDs(
248
- object_ids=descendants + [msg_object_id]
249
- )
250
+ # Add mapping of message object ID to its descendants
251
+ objects_to_pull[msg_object_id] = ObjectIDs(object_ids=descendants)
250
252
  except NoObjectInStoreError as e:
251
253
  log(ERROR, e.message)
252
254
  # Delete message ins from state
@@ -29,6 +29,7 @@ from flwr.common.typing import UserConfig
29
29
  from flwr.proto.exec_pb2_grpc import add_ExecServicer_to_server
30
30
  from flwr.server.superlink.ffs.ffs_factory import FfsFactory
31
31
  from flwr.server.superlink.linkstate import LinkStateFactory
32
+ from flwr.supercore.object_store import ObjectStoreFactory
32
33
  from flwr.superexec.exec_event_log_interceptor import ExecEventLogInterceptor
33
34
  from flwr.superexec.exec_user_auth_interceptor import ExecUserAuthInterceptor
34
35
 
@@ -42,6 +43,7 @@ def run_exec_api_grpc(
42
43
  executor: Executor,
43
44
  state_factory: LinkStateFactory,
44
45
  ffs_factory: FfsFactory,
46
+ objectstore_factory: ObjectStoreFactory,
45
47
  certificates: Optional[tuple[bytes, bytes, bytes]],
46
48
  config: UserConfig,
47
49
  auth_plugin: Optional[ExecAuthPlugin] = None,
@@ -54,6 +56,7 @@ def run_exec_api_grpc(
54
56
  exec_servicer: grpc.Server = ExecServicer(
55
57
  linkstate_factory=state_factory,
56
58
  ffs_factory=ffs_factory,
59
+ objectstore_factory=objectstore_factory,
57
60
  executor=executor,
58
61
  auth_plugin=auth_plugin,
59
62
  )
@@ -18,20 +18,25 @@
18
18
  import time
19
19
  from collections.abc import Generator
20
20
  from logging import ERROR, INFO
21
- from typing import Any, Optional
21
+ from typing import Any, Optional, cast
22
22
 
23
23
  import grpc
24
24
 
25
25
  from flwr.common import now
26
26
  from flwr.common.auth_plugin import ExecAuthPlugin
27
- from flwr.common.constant import LOG_STREAM_INTERVAL, Status, SubStatus
27
+ from flwr.common.constant import (
28
+ LOG_STREAM_INTERVAL,
29
+ RUN_ID_NOT_FOUND_MESSAGE,
30
+ Status,
31
+ SubStatus,
32
+ )
28
33
  from flwr.common.logger import log
29
34
  from flwr.common.serde import (
30
35
  config_record_from_proto,
31
36
  run_to_proto,
32
37
  user_config_from_proto,
33
38
  )
34
- from flwr.common.typing import RunStatus
39
+ from flwr.common.typing import Run, RunStatus
35
40
  from flwr.proto import exec_pb2_grpc # pylint: disable=E0611
36
41
  from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
37
42
  GetAuthTokensRequest,
@@ -49,6 +54,7 @@ from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
49
54
  )
50
55
  from flwr.server.superlink.ffs.ffs_factory import FfsFactory
51
56
  from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
57
+ from flwr.supercore.object_store import ObjectStore, ObjectStoreFactory
52
58
 
53
59
  from .exec_user_auth_interceptor import shared_account_info
54
60
  from .executor import Executor
@@ -57,15 +63,17 @@ from .executor import Executor
57
63
  class ExecServicer(exec_pb2_grpc.ExecServicer):
58
64
  """SuperExec API servicer."""
59
65
 
60
- def __init__(
66
+ def __init__( # pylint: disable=R0913, R0917
61
67
  self,
62
68
  linkstate_factory: LinkStateFactory,
63
69
  ffs_factory: FfsFactory,
70
+ objectstore_factory: ObjectStoreFactory,
64
71
  executor: Executor,
65
72
  auth_plugin: Optional[ExecAuthPlugin] = None,
66
73
  ) -> None:
67
74
  self.linkstate_factory = linkstate_factory
68
75
  self.ffs_factory = ffs_factory
76
+ self.objectstore_factory = objectstore_factory
69
77
  self.executor = executor
70
78
  self.executor.initialize(linkstate_factory, ffs_factory)
71
79
  self.auth_plugin = auth_plugin
@@ -97,12 +105,20 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
97
105
  log(INFO, "ExecServicer.StreamLogs")
98
106
  state = self.linkstate_factory.state()
99
107
 
100
- # Retrieve run ID
108
+ # Retrieve run ID and run
101
109
  run_id = request.run_id
110
+ run = state.get_run(run_id)
102
111
 
103
112
  # Exit if `run_id` not found
104
- if not state.get_run(run_id):
105
- context.abort(grpc.StatusCode.NOT_FOUND, "Run ID not found")
113
+ if not run:
114
+ context.abort(grpc.StatusCode.NOT_FOUND, RUN_ID_NOT_FOUND_MESSAGE)
115
+
116
+ # If user auth is enabled, check if `flwr_aid` matches the run's `flwr_aid`
117
+ if self.auth_plugin:
118
+ flwr_aid = shared_account_info.get().flwr_aid
119
+ _check_flwr_aid_in_run(
120
+ flwr_aid=flwr_aid, run=cast(Run, run), context=context
121
+ )
106
122
 
107
123
  after_timestamp = request.after_timestamp + 1e-6
108
124
  while context.is_active():
@@ -121,7 +137,10 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
121
137
  # is returned at this point and the server ends the stream.
122
138
  run_status = state.get_run_status({run_id})[run_id]
123
139
  if run_status.status == Status.FINISHED:
124
- log(INFO, "All logs for run ID `%s` returned", request.run_id)
140
+ log(INFO, "All logs for run ID `%s` returned", run_id)
141
+
142
+ # Delete objects of the run from the object store
143
+ self.objectstore_factory.store().delete_objects_in_run(run_id)
125
144
  break
126
145
 
127
146
  time.sleep(LOG_STREAM_INTERVAL) # Sleep briefly to avoid busy waiting
@@ -133,11 +152,44 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
133
152
  log(INFO, "ExecServicer.List")
134
153
  state = self.linkstate_factory.state()
135
154
 
136
- # Handle `flwr ls --runs`
155
+ # Build a set of run IDs for `flwr ls --runs`
137
156
  if not request.HasField("run_id"):
138
- return _create_list_runs_response(state.get_run_ids(None), state)
139
- # Handle `flwr ls --run-id <run_id>`
140
- return _create_list_runs_response({request.run_id}, state)
157
+ if self.auth_plugin:
158
+ # If no `run_id` is specified and user auth is enabled,
159
+ # return run IDs for the authenticated user
160
+ flwr_aid = shared_account_info.get().flwr_aid
161
+ if flwr_aid is None:
162
+ context.abort(
163
+ grpc.StatusCode.PERMISSION_DENIED,
164
+ "️⛔️ User authentication is enabled, but `flwr_aid` is None",
165
+ )
166
+ run_ids = state.get_run_ids(flwr_aid=flwr_aid)
167
+ else:
168
+ # If no `run_id` is specified and no user auth is enabled,
169
+ # return all run IDs
170
+ run_ids = state.get_run_ids(None)
171
+ # Build a set of run IDs for `flwr ls --run-id <run_id>`
172
+ else:
173
+ # Retrieve run ID and run
174
+ run_id = request.run_id
175
+ run = state.get_run(run_id)
176
+
177
+ # Exit if `run_id` not found
178
+ if not run:
179
+ context.abort(grpc.StatusCode.NOT_FOUND, RUN_ID_NOT_FOUND_MESSAGE)
180
+
181
+ # If user auth is enabled, check if `flwr_aid` matches the run's `flwr_aid`
182
+ if self.auth_plugin:
183
+ flwr_aid = shared_account_info.get().flwr_aid
184
+ _check_flwr_aid_in_run(
185
+ flwr_aid=flwr_aid, run=cast(Run, run), context=context
186
+ )
187
+
188
+ run_ids = {run_id}
189
+
190
+ # Init the object store
191
+ store = self.objectstore_factory.store()
192
+ return _create_list_runs_response(run_ids, state, store)
141
193
 
142
194
  def StopRun(
143
195
  self, request: StopRunRequest, context: grpc.ServicerContext
@@ -146,30 +198,42 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
146
198
  log(INFO, "ExecServicer.StopRun")
147
199
  state = self.linkstate_factory.state()
148
200
 
201
+ # Retrieve run ID and run
202
+ run_id = request.run_id
203
+ run = state.get_run(run_id)
204
+
149
205
  # Exit if `run_id` not found
150
- if not state.get_run(request.run_id):
151
- context.abort(
152
- grpc.StatusCode.NOT_FOUND, f"Run ID {request.run_id} not found"
206
+ if not run:
207
+ context.abort(grpc.StatusCode.NOT_FOUND, RUN_ID_NOT_FOUND_MESSAGE)
208
+
209
+ # If user auth is enabled, check if `flwr_aid` matches the run's `flwr_aid`
210
+ if self.auth_plugin:
211
+ flwr_aid = shared_account_info.get().flwr_aid
212
+ _check_flwr_aid_in_run(
213
+ flwr_aid=flwr_aid, run=cast(Run, run), context=context
153
214
  )
154
215
 
155
- run_status = state.get_run_status({request.run_id})[request.run_id]
216
+ run_status = state.get_run_status({run_id})[run_id]
156
217
  if run_status.status == Status.FINISHED:
157
218
  context.abort(
158
219
  grpc.StatusCode.FAILED_PRECONDITION,
159
- f"Run ID {request.run_id} is already finished",
220
+ f"Run ID {run_id} is already finished",
160
221
  )
161
222
 
162
223
  update_success = state.update_run_status(
163
- run_id=request.run_id,
224
+ run_id=run_id,
164
225
  new_status=RunStatus(Status.FINISHED, SubStatus.STOPPED, ""),
165
226
  )
166
227
 
167
228
  if update_success:
168
- message_ids: set[str] = state.get_message_ids_from_run_id(request.run_id)
229
+ message_ids: set[str] = state.get_message_ids_from_run_id(run_id)
169
230
 
170
231
  # Delete Messages and their replies for the `run_id`
171
232
  state.delete_messages(message_ids)
172
233
 
234
+ # Delete objects of the run from the object store
235
+ self.objectstore_factory.store().delete_objects_in_run(run_id)
236
+
173
237
  return StopRunResponse(success=update_success)
174
238
 
175
239
  def GetLoginDetails(
@@ -224,10 +288,46 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
224
288
  )
225
289
 
226
290
 
227
- def _create_list_runs_response(run_ids: set[int], state: LinkState) -> ListRunsResponse:
291
+ def _create_list_runs_response(
292
+ run_ids: set[int], state: LinkState, store: ObjectStore
293
+ ) -> ListRunsResponse:
228
294
  """Create response for `flwr ls --runs` and `flwr ls --run-id <run_id>`."""
229
- run_dict = {run_id: state.get_run(run_id) for run_id in run_ids}
295
+ run_dict = {run_id: run for run_id in run_ids if (run := state.get_run(run_id))}
296
+
297
+ # Delete objects of finished runs from the object store
298
+ for run_id, run in run_dict.items():
299
+ if run.status.status == Status.FINISHED:
300
+ store.delete_objects_in_run(run_id)
301
+
230
302
  return ListRunsResponse(
231
- run_dict={run_id: run_to_proto(run) for run_id, run in run_dict.items() if run},
303
+ run_dict={run_id: run_to_proto(run) for run_id, run in run_dict.items()},
232
304
  now=now().isoformat(),
233
305
  )
306
+
307
+
308
+ def _check_flwr_aid_in_run(
309
+ flwr_aid: Optional[str], run: Run, context: grpc.ServicerContext
310
+ ) -> None:
311
+ """Guard clause to check if `flwr_aid` matches the run's `flwr_aid`."""
312
+ # `flwr_aid` must not be None. Abort if it is None.
313
+ if flwr_aid is None:
314
+ context.abort(
315
+ grpc.StatusCode.PERMISSION_DENIED,
316
+ "️⛔️ User authentication is enabled, but `flwr_aid` is None",
317
+ )
318
+
319
+ # `run.flwr_aid` must not be an empty string. Abort if it is empty.
320
+ run_flwr_aid = run.flwr_aid
321
+ if not run_flwr_aid:
322
+ context.abort(
323
+ grpc.StatusCode.PERMISSION_DENIED,
324
+ "⛔️ User authentication is enabled, but the run is not associated "
325
+ "with a `flwr_aid`.",
326
+ )
327
+
328
+ # Exit if `flwr_aid` does not match the run's `flwr_aid`
329
+ if run_flwr_aid != flwr_aid:
330
+ context.abort(
331
+ grpc.StatusCode.PERMISSION_DENIED,
332
+ "⛔️ Run ID does not belong to the user",
333
+ )
@@ -241,11 +241,20 @@ def start_client_internal(
241
241
  outputs = clientappio_servicer.get_outputs()
242
242
  reply_message, context = outputs.message, outputs.context
243
243
 
244
- # Update node state
244
+ # Update context in the state
245
245
  state.store_context(context)
246
246
 
247
247
  # Send
248
248
  send(reply_message)
249
+
250
+ # Delete messages from the state
251
+ state.delete_messages(
252
+ message_ids=[
253
+ message.metadata.message_id,
254
+ message.metadata.reply_to_message_id,
255
+ ]
256
+ )
257
+
249
258
  log(INFO, "Sent reply")
250
259
 
251
260
  except RunNotRunningException:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.19.0.dev20250612
3
+ Version: 1.19.0.dev20250616
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
@@ -15,7 +15,7 @@ flwr/cli/install.py,sha256=Jr883qR7qssVpUr3hEOEcLK-dfW67Rsve3lZchjA9RU,8180
15
15
  flwr/cli/log.py,sha256=CKh5l2nnpognDy3lSubrlYX2-gNJ0qa-UFGVPRKS_YQ,6523
16
16
  flwr/cli/login/__init__.py,sha256=B1SXKU3HCQhWfFDMJhlC7FOl8UsvH4mxysxeBnrfyUE,800
17
17
  flwr/cli/login/login.py,sha256=pDkx5o4XBFBi7aGp_0Ys2FUMKmcWjzwWdoQRumXUsd8,4297
18
- flwr/cli/ls.py,sha256=RpOR6tEyu5TWWMIAUa23cxuKH3yfBoki7UQigpIT3TY,11427
18
+ flwr/cli/ls.py,sha256=zBBO3Yom3DIYwIJg09OSxy347wiYffOviqh-c2U4A04,10939
19
19
  flwr/cli/new/__init__.py,sha256=QA1E2QtzPvFCjLTUHnFnJbufuFiGyT_0Y53Wpbvg1F0,790
20
20
  flwr/cli/new/new.py,sha256=2e4ACJqeZ0W0_FyksQTi7PEzQpXT8KRpBPthFoac6zQ,9917
21
21
  flwr/cli/new/templates/__init__.py,sha256=FpjWCfIySU2DB4kh0HOXLAjlZNNFDTVU4w3HoE2TzcI,725
@@ -73,7 +73,7 @@ flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=7aOtbvAAnVXyTEYL
73
73
  flwr/cli/run/__init__.py,sha256=RPyB7KbYTFl6YRiilCch6oezxrLQrl1kijV7BMGkLbA,790
74
74
  flwr/cli/run/run.py,sha256=U_EHebzwiH8Lszm40oJM8a2I0vaiu1Iizci_GHSl25Y,8211
75
75
  flwr/cli/stop.py,sha256=l8DcRkA---CESVJgc7iTHLWIBAPGxWIfoem8qSU3lZQ,4972
76
- flwr/cli/utils.py,sha256=brzc0HPhFxJDi4ctfyQi9lW35uOyvQzoOJ8XHeMDIfE,11575
76
+ flwr/cli/utils.py,sha256=Vyxpd8LOn2tg5wwId18CHDKq2xaoFDxHMnMW0IlG9Yw,12048
77
77
  flwr/client/__init__.py,sha256=boIhKaK6I977zrILmoTutNx94x5jB0e6F1gnAjaRJnI,1250
78
78
  flwr/client/client.py,sha256=3HAchxvknKG9jYbB7swNyDj-e5vUWDuMKoLvbT7jCVM,7895
79
79
  flwr/client/client_app.py,sha256=zVhi-l3chAb06ozFsKwix3hU_RpOLjST13Ha50AVIPE,16918
@@ -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=A8rWHZZUH4Rxbx-bCKW5pNJ_BG4W9Xfw4fLevNhZ8l0,8077
111
+ flwr/common/constant.py,sha256=yCJk_m7sJiMz8fTmOMWLBzltGRVUjFmt9NoYJt3Fz-w,8150
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
@@ -226,7 +226,7 @@ flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPc
226
226
  flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
227
227
  flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
228
228
  flwr/server/__init__.py,sha256=LQQHiuL2jy7TpNaKastRdGsexlxSt5ZWAQNVqitDnrY,1598
229
- flwr/server/app.py,sha256=eI8oXdpYgHCVPNGqcyAxubxFd8huW1t3kE0tc9JKfCw,29878
229
+ flwr/server/app.py,sha256=reOCH1YmngNxWXBvxp8UfQNTfLP95NMh8j8jU0dW1IU,29492
230
230
  flwr/server/client_manager.py,sha256=5jCGavVli7XdupvWWo7ru3PdFTlRU8IGvHFSSoUVLRs,6227
231
231
  flwr/server/client_proxy.py,sha256=sv0E9AldBYOvc3pusqFh-GnyreeMfsXQ1cuTtxTq_wY,2399
232
232
  flwr/server/compat/__init__.py,sha256=0IsttWvY15qO98_1GyzVC-vR1e_ZPXOdu2qUlOkYMPE,886
@@ -298,14 +298,14 @@ flwr/server/superlink/fleet/vce/backend/backend.py,sha256=-wDHjgAy5mrfEgXj0GxkJI
298
298
  flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=Hx9hxL7lju1_VJoAwkhBOGerZ3628u0P1zgkPhGWRPY,7154
299
299
  flwr/server/superlink/fleet/vce/vce_api.py,sha256=xSjQbBYHmUTinw7Q_-UxqR7qt07kqj9FCSpPYRsUKf8,12909
300
300
  flwr/server/superlink/linkstate/__init__.py,sha256=OtsgvDTnZLU3k0sUbkHbqoVwW6ql2FDmb6uT6DbNkZo,1064
301
- flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=gGA1qo-h_Rvvdv99qg112CjD8PmI_0kMjAxo4ER2piE,26350
301
+ flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=OuyuW_btDL-Nuon2aAcyXDapzwzZX4PrRWTjb0epoaI,26478
302
302
  flwr/server/superlink/linkstate/linkstate.py,sha256=JZHshn7NnUHr_hvHqO593YWwuCQVJm7InXor60DRcX0,13238
303
303
  flwr/server/superlink/linkstate/linkstate_factory.py,sha256=8RlosqSpKOoD_vhUUQPY0jtE3A84GeF96Z7sWNkRRcA,2069
304
304
  flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=E699Ak0jMF3N7i1SIeFRutjorg51Fd7qBqaPX_gkWU0,43687
305
305
  flwr/server/superlink/linkstate/utils.py,sha256=IeLh7iGRCHU5MEWOl7iriaSE4L__8GWOa2OleXadK5M,15444
306
306
  flwr/server/superlink/serverappio/__init__.py,sha256=Fy4zJuoccZe5mZSEIpOmQvU6YeXFBa1M4eZuXXmJcn8,717
307
307
  flwr/server/superlink/serverappio/serverappio_grpc.py,sha256=6-FUUt0GiLcBPljj8bBrUNeAITUoDQOLzaMihKo52hg,2326
308
- flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=LFt_Wu2OOmbNQWZrLW6GoQFdvZ60bupF4c7lvLF7kDw,18617
308
+ flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=pjBjZ6NQdOKO3AYZ8tGD-wzGHh4LaVS3lpPZb6XpKU8,18823
309
309
  flwr/server/superlink/simulation/__init__.py,sha256=Ry8DrNaZCMcQXvUc4FoCN2m3dvUQgWjasfp015o3Ec4,718
310
310
  flwr/server/superlink/simulation/simulationio_grpc.py,sha256=0l0F-UjYEk6W7HZmI28PbJQLFxSi_vBHRkdchgdaSMQ,2224
311
311
  flwr/server/superlink/simulation/simulationio_servicer.py,sha256=8jACbVPe7YPLaR0hbpEofBBwWjc-uQPhf2FU1eNOtsw,7743
@@ -339,8 +339,8 @@ flwr/superexec/__init__.py,sha256=YFqER0IJc1XEWfsX6AxZ9LSRq0sawPYrNYki-brvTIc,71
339
339
  flwr/superexec/app.py,sha256=U2jjOHb2LGWoU7vrl9_czTzre9O2mPxu3CPGUZ86sK4,1465
340
340
  flwr/superexec/deployment.py,sha256=aDTRCM2V9iVS_gvwTSGaRIPGkm2Ro-CxFYin-Mba0P8,6853
341
341
  flwr/superexec/exec_event_log_interceptor.py,sha256=7aBjZ4lkpOIyWut0s394OpMePr16g_Te594s-9aDM9Q,5774
342
- flwr/superexec/exec_grpc.py,sha256=LS-CrwBayHQAvJz-zmzV5JsaEC49VumsS25nC0NgYXg,3364
343
- flwr/superexec/exec_servicer.py,sha256=5bhBzEMwsWxJozSXONcRYqHp2OVwIUMhKFtIxmaF4c8,8494
342
+ flwr/superexec/exec_grpc.py,sha256=oM9-cwTpZGRI3ma4wc9Xt5RwtM1GzrmCRmiOgr3jT34,3517
343
+ flwr/superexec/exec_servicer.py,sha256=E70y-r17GOsCEwQvVmcDyJYp_H7fse4cxha6Gbgnaqo,12254
344
344
  flwr/superexec/exec_user_auth_interceptor.py,sha256=HpGHTcDKzB7XUiQHXgntNVFYL-VfP9Wj5tEVc04VOOw,5820
345
345
  flwr/superexec/executor.py,sha256=6kazVVypj-jtfeaHsqGElOv7FCrfqeQotYxVx1m4y84,3284
346
346
  flwr/superexec/simulation.py,sha256=2iRVsC2dGLuqIAvwsznt_qE3u9A-yuPsj9q94Oit_As,4212
@@ -358,8 +358,8 @@ flwr/supernode/runtime/run_clientapp.py,sha256=cvWSby7u31u97QapWHxJM-Wer6F1k6mbb
358
358
  flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca8gxdEo,717
359
359
  flwr/supernode/servicer/clientappio/__init__.py,sha256=vJyOjO2FXZ2URbnthmdsgs6948wbYfdq1L1V8Um-Lr8,895
360
360
  flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=LmzkxtNQBn5vVrHc0Bhq2WqaK6-LM2v4kfLBN0PiNNM,8522
361
- flwr/supernode/start_client_internal.py,sha256=AkJ1FsBK6EpK7cmIGcae5WZazPhU71gileiSQogTZ-k,18164
362
- flwr_nightly-1.19.0.dev20250612.dist-info/METADATA,sha256=XKojy0erL7FqHBslIYb56XNVEdor9P2F0mKQRV81t7U,15910
363
- flwr_nightly-1.19.0.dev20250612.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
364
- flwr_nightly-1.19.0.dev20250612.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
365
- flwr_nightly-1.19.0.dev20250612.dist-info/RECORD,,
361
+ flwr/supernode/start_client_internal.py,sha256=M1_sYScUzhXAg1obVf64E6UxYP0m9g6OmA2vZiB75As,18453
362
+ flwr_nightly-1.19.0.dev20250616.dist-info/METADATA,sha256=dzYxYe5YgeuTZHTSGgctOaiLXYFPBczS5POBfjrRTv4,15910
363
+ flwr_nightly-1.19.0.dev20250616.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
364
+ flwr_nightly-1.19.0.dev20250616.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
365
+ flwr_nightly-1.19.0.dev20250616.dist-info/RECORD,,