flwr-nightly 1.20.0.dev20250728__py3-none-any.whl → 1.21.0.dev20250730__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.
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets[vision]>=0.5.0",
19
19
  "torch==2.7.1",
20
20
  "torchvision==0.22.1",
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets>=0.5.0",
19
19
  "torch==2.4.0",
20
20
  "trl==0.8.1",
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets>=0.5.0",
19
19
  "torch==2.7.1",
20
20
  "transformers>=4.30.0,<5.0",
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "jax==0.4.30",
19
19
  "jaxlib==0.4.30",
20
20
  "scikit-learn==1.6.1",
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets[vision]>=0.5.0",
19
19
  "mlx==0.26.5",
20
20
  ]
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "numpy>=2.0.2",
19
19
  ]
20
20
 
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets[vision]>=0.5.0",
19
19
  "torch==2.7.1",
20
20
  "torchvision==0.22.1",
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets[vision]>=0.5.0",
19
19
  "scikit-learn>=1.6.1",
20
20
  ]
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets[vision]>=0.5.0",
19
19
  "tensorflow>=2.11.1,<2.18.0",
20
20
  ]
@@ -34,6 +34,7 @@ from .constant import (
34
34
  PULL_MAX_TIME,
35
35
  PULL_MAX_TRIES_PER_OBJECT,
36
36
  )
37
+ from .exit_handlers import add_exit_handler
37
38
  from .inflatable import (
38
39
  InflatableObject,
39
40
  UnexpectedObjectContentError,
@@ -61,6 +62,34 @@ inflatable_class_registry: dict[str, type[InflatableObject]] = {
61
62
  T = TypeVar("T", bound=InflatableObject)
62
63
 
63
64
 
65
+ # Allow thread pool executors to be shut down gracefully
66
+ _thread_pool_executors: set[concurrent.futures.ThreadPoolExecutor] = set()
67
+ _lock = threading.Lock()
68
+
69
+
70
+ def _shutdown_thread_pool_executors() -> None:
71
+ """Shutdown all thread pool executors gracefully."""
72
+ with _lock:
73
+ for executor in _thread_pool_executors:
74
+ executor.shutdown(wait=False, cancel_futures=True)
75
+ _thread_pool_executors.clear()
76
+
77
+
78
+ def _track_executor(executor: concurrent.futures.ThreadPoolExecutor) -> None:
79
+ """Track a thread pool executor for graceful shutdown."""
80
+ with _lock:
81
+ _thread_pool_executors.add(executor)
82
+
83
+
84
+ def _untrack_executor(executor: concurrent.futures.ThreadPoolExecutor) -> None:
85
+ """Untrack a thread pool executor."""
86
+ with _lock:
87
+ _thread_pool_executors.discard(executor)
88
+
89
+
90
+ add_exit_handler(_shutdown_thread_pool_executors)
91
+
92
+
64
93
  class ObjectUnavailableError(Exception):
65
94
  """Exception raised when an object has been pre-registered but is not yet
66
95
  available."""
@@ -165,7 +194,16 @@ def push_object_contents_from_iterable(
165
194
  # Push all object contents concurrently
166
195
  num_workers = get_num_workers(max_concurrent_pushes)
167
196
  with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
168
- list(executor.map(push, object_contents))
197
+ # Ensure that the thread pool executors are tracked for graceful shutdown
198
+ _track_executor(executor)
199
+
200
+ # Submit push tasks for each object content
201
+ executor.map(push, object_contents) # Non-blocking map
202
+
203
+ # The context manager will block until all submitted tasks have completed
204
+
205
+ # Remove the executor from the list of tracked executors
206
+ _untrack_executor(executor)
169
207
 
170
208
 
171
209
  def pull_objects( # pylint: disable=too-many-arguments,too-many-locals
@@ -262,13 +300,18 @@ def pull_objects( # pylint: disable=too-many-arguments,too-many-locals
262
300
  # Submit all pull tasks concurrently
263
301
  num_workers = get_num_workers(max_concurrent_pulls)
264
302
  with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
265
- futures = {
266
- executor.submit(pull_with_retries, obj_id): obj_id for obj_id in object_ids
267
- }
303
+ # Ensure that the thread pool executors are tracked for graceful shutdown
304
+ _track_executor(executor)
305
+
306
+ # Submit pull tasks for each object ID
307
+ executor.map(pull_with_retries, object_ids) # Non-blocking map
308
+
309
+ # The context manager will block until all submitted tasks have completed
268
310
 
269
- # Wait for completion
270
- concurrent.futures.wait(futures)
311
+ # Remove the executor from the list of tracked executors
312
+ _untrack_executor(executor)
271
313
 
314
+ # If an error occurred during pulling, raise it
272
315
  if err_to_raise is not None:
273
316
  raise err_to_raise
274
317
 
@@ -16,6 +16,7 @@
16
16
 
17
17
 
18
18
  import argparse
19
+ import gc
19
20
  from logging import DEBUG, ERROR, INFO
20
21
  from pathlib import Path
21
22
  from queue import Queue
@@ -115,6 +116,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
115
116
  run_status = None
116
117
  heartbeat_sender = None
117
118
  grid = None
119
+ context = None
118
120
  while True:
119
121
 
120
122
  try:
@@ -248,6 +250,10 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
248
250
  if grid:
249
251
  grid.close()
250
252
 
253
+ # Clean up the Context
254
+ context = None
255
+ gc.collect()
256
+
251
257
  event(
252
258
  EventType.FLWR_SERVERAPP_RUN_LEAVE,
253
259
  event_details={"run-id-hash": hash_run_id, "success": success},
flwr/simulation/app.py CHANGED
@@ -16,6 +16,7 @@
16
16
 
17
17
 
18
18
  import argparse
19
+ import gc
19
20
  from logging import DEBUG, ERROR, INFO
20
21
  from queue import Queue
21
22
  from time import sleep
@@ -271,6 +272,13 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09
271
272
  )
272
273
  )
273
274
 
275
+ # Clean up the Context if it exists
276
+ try:
277
+ del updated_context
278
+ except NameError:
279
+ pass
280
+ gc.collect()
281
+
274
282
  # Stop the loop if `flwr-simulation` is expected to process a single run
275
283
  if run_once:
276
284
  break
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.20.0.dev20250728
3
+ Version: 1.21.0.dev20250730
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
@@ -61,15 +61,15 @@ flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=XlJqA4Ix_PloO_zJLhjiN
61
61
  flwr/cli/new/templates/app/code/task.sklearn.py.tpl,sha256=vHdhtMp0FHxbYafXyhDT9aKmmmA0Jvpx5Oum1Yu9lWY,1850
62
62
  flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=SKXAZdgBnPpbAbJ90Rb7oQ5ilnopBx_j_JNFoUDeEAI,1732
63
63
  flwr/cli/new/templates/app/code/utils.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
64
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=SHhqI-Qg-ufOjkEKJtUtigwbpZRDg-EN0U64puJlsPE,3180
65
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=iPylV_q02Nsfp1sfgX6VkB-U4ezgOfL3nc8mlKjNMxw,2497
66
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=-DFFc6AuJOGA2lELLiwahDOG7iQjQ2OOXC7XcZ_fqWQ,2019
67
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=UEMslvDDoeNwcyMqcYon4t_OmdR3Q8o0I4yAj1cWpBo,1471
68
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=Mcr05KhDdg5G-QatS8c4A6H8RPH2Br6YjV7Z5gjkQXA,1542
69
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=_UrN9JddlNv97OkSjViJIkO0WUoMUTaZkbCLbs7Dg2A,1409
70
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=2Bkk42w4djEpBfCnOyFzSkCy6QklGnGR0mu7jtRZ8xo,1508
71
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=FXuh0UjbXUg488FZmP9GTXZiiSAIbr7L3SxSqkjokhw,1484
72
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=kjTToUNkLHn7OXNypG3WPEgt2g_DqoKPdm37x8ScFHw,1508
64
+ flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=o7WJPF7lH_azNTiUrvTtLfXKyAY3_xTzwvUpkp3suUI,3180
65
+ flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=zDNuDkvgVI7SNK7RLSlaFs2LhSW1-THDKNBJVw1_y78,2497
66
+ flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=dsjlA0aS-U7xzB7YCYMOGVb7a0XJTB5bsemFzwUPkPg,2019
67
+ flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=BHGb2N57Xm2scO1mqDSNgK_aiI68mRh6u4Y9TLL5bZE,1471
68
+ flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=O6eN6Zqx2ieh-WbaiMYmxfhCrLKJjwymn_nhUDEOldM,1542
69
+ flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=oMTI8qXSgQsGlZextUpkWFvNOMlnWbzn2EocPSwDrtw,1409
70
+ flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=bu65oSrM85fP_H0-RlMS2i8XgL_8O5TfSHLW87lb30s,1508
71
+ flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=mAEPeBfGyrINgRuP6-nX_KJNTQjC4E5N1Nrcddxiffs,1484
72
+ flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=mK8wOWqoQOVxZG6-OVwA2ChmKxexC7TfQV0ztPE4BWY,1508
73
73
  flwr/cli/run/__init__.py,sha256=RPyB7KbYTFl6YRiilCch6oezxrLQrl1kijV7BMGkLbA,790
74
74
  flwr/cli/run/run.py,sha256=psmr215gkV0e0QtX9NFp7KUwKSA_ZwekdJmoL1zFyfw,8478
75
75
  flwr/cli/stop.py,sha256=l8DcRkA---CESVJgc7iTHLWIBAPGxWIfoem8qSU3lZQ,4972
@@ -124,7 +124,7 @@ flwr/common/grpc.py,sha256=y70hUFvXkIf3l03xOhlb7qhS6W1UJZRSZqCdB0ir0v8,10381
124
124
  flwr/common/heartbeat.py,sha256=SyEpNDnmJ0lni0cWO67rcoJVKasCLmkNHm3dKLeNrLU,5749
125
125
  flwr/common/inflatable.py,sha256=GDL9oBKs16_yyVdlH6kBf493O5xll_h9V7XB5Mpx1Hc,9524
126
126
  flwr/common/inflatable_protobuf_utils.py,sha256=JtRqp-fV47goDM2y8JRQ7AmwwjeGaWexwoMWLcxX5gE,5056
127
- flwr/common/inflatable_utils.py,sha256=tYNrsdUWIw94p1oBPojg2wlD_-tnspWU2tbmIRafB6U,17401
127
+ flwr/common/inflatable_utils.py,sha256=OcNW8_CfHNuJhHekwRtnrDJZ4vbhujw2w7SG7Y0TuSI,18955
128
128
  flwr/common/logger.py,sha256=JbRf6E2vQxXzpDBq1T8IDUJo_usu3gjWEBPQ6uKcmdg,13049
129
129
  flwr/common/message.py,sha256=xAL7iZN5-n-xPQpgoSFvxNrzs8fmiiPfoU0DjNQEhRw,19953
130
130
  flwr/common/object_ref.py,sha256=p3SfTeqo3Aj16SkB-vsnNn01zswOPdGNBitcbRnqmUk,9134
@@ -250,7 +250,7 @@ flwr/server/server.py,sha256=39m4FSN2T-uVA-no9nstN0eWW0co-IUUAIMmpd3V7Jc,17893
250
250
  flwr/server/server_app.py,sha256=8uagoZX-3CY3tazPqkIV9jY-cN0YrRRrDmVe23o0AV0,9515
251
251
  flwr/server/server_config.py,sha256=e_6ddh0riwOJsdNn2BFev344uMWfDk9n7dyjNpPgm1w,1349
252
252
  flwr/server/serverapp/__init__.py,sha256=xcC0T_MQSMS9cicUzUUpMNCOsF2d8Oh_8jvnoBLuZvo,800
253
- flwr/server/serverapp/app.py,sha256=GetSKAsDlNlJFazregZ_Vu63SIIL9KrZXEvSjND7qA0,9407
253
+ flwr/server/serverapp/app.py,sha256=k0wAdZiMAEz7WsUigxv038I5Eel3vXwuSqGGj2HtX3c,9524
254
254
  flwr/server/serverapp_components.py,sha256=dfSqmrsVy3arKXpl3ZIBQWdV8rehfIms8aJooyzdmEM,2118
255
255
  flwr/server/strategy/__init__.py,sha256=HhsSWMWaC7oCb2g7Kqn1MBKdrfvgi8VxACy9ZL706Q0,2836
256
256
  flwr/server/strategy/aggregate.py,sha256=smlKKy-uFUuuFR12vlclucnwSQWRz78R79-Km4RWqbw,13978
@@ -322,7 +322,7 @@ flwr/server/workflow/secure_aggregation/secagg_workflow.py,sha256=b_pKk7gmbahwyj
322
322
  flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=DkayCsnlAya6Y2PZsueLgoUCMRtV-GbnW08RfWx_SXM,29460
323
323
  flwr/serverapp/__init__.py,sha256=HPvC_ZvMS7GCM7ALVrG_Wwm4bSDr4DZETeC561v3T9w,719
324
324
  flwr/simulation/__init__.py,sha256=Gg6OsP1Z-ixc3-xxzvl7j7rz2Fijy9rzyEPpxgAQCeM,1556
325
- flwr/simulation/app.py,sha256=Uy3lPwAvfZECkWPLcC0oDXTwY14e4ou8itIcBltjmWE,10437
325
+ flwr/simulation/app.py,sha256=hP7vP29qZOA_3dipzUdmkRXP25eS8RlF1MT-S09t3oc,10625
326
326
  flwr/simulation/legacy_app.py,sha256=nMISQqW0otJL1-2Kfd94O6BLlGS2IEmEPKTM2WGKrIs,15861
327
327
  flwr/simulation/ray_transport/__init__.py,sha256=ogd-0AMv2U-wBZ1r3sHWaDIOIrVqr88Xi6C8o4Dviy0,734
328
328
  flwr/simulation/ray_transport/ray_actor.py,sha256=JN3xTqFIr5Z750k92CcA_uavzOHhSWDwE2WCaecvpks,19147
@@ -374,7 +374,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
374
374
  flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
375
375
  flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=ClPoKco7Tjj_cxRPhZlQSrOvcGa8sJwGs26LUNZnI3Y,10608
376
376
  flwr/supernode/start_client_internal.py,sha256=VC7rV4QaX5Vk4Lw0DDodhwsKvGiHbr0mqrV0H77h1UI,21999
377
- flwr_nightly-1.20.0.dev20250728.dist-info/METADATA,sha256=-zyMPgvOSZXpWwguchnub0MLUqMNBwguXF_FngYI2Vw,15966
378
- flwr_nightly-1.20.0.dev20250728.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
379
- flwr_nightly-1.20.0.dev20250728.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
380
- flwr_nightly-1.20.0.dev20250728.dist-info/RECORD,,
377
+ flwr_nightly-1.21.0.dev20250730.dist-info/METADATA,sha256=H636xLDJ-N3ab4OnF9d7Scj16WrGekbgQAonr7E0s34,15966
378
+ flwr_nightly-1.21.0.dev20250730.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
379
+ flwr_nightly-1.21.0.dev20250730.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
380
+ flwr_nightly-1.21.0.dev20250730.dist-info/RECORD,,