flwr-nightly 1.23.0.dev20251027__py3-none-any.whl → 1.23.0.dev20251029__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.

Potentially problematic release.


This version of flwr-nightly might be problematic. Click here for more details.

@@ -99,6 +99,10 @@ SQL_CREATE_INDEX_OWNER_AID = """
99
99
  CREATE INDEX IF NOT EXISTS idx_node_owner_aid ON node(owner_aid);
100
100
  """
101
101
 
102
+ SQL_CREATE_INDEX_NODE_STATUS = """
103
+ CREATE INDEX IF NOT EXISTS idx_node_status ON node(status);
104
+ """
105
+
102
106
  SQL_CREATE_TABLE_RUN = """
103
107
  CREATE TABLE IF NOT EXISTS run(
104
108
  run_id INTEGER UNIQUE,
@@ -199,6 +203,7 @@ class SqliteLinkState(LinkState, SqliteMixin): # pylint: disable=R0904
199
203
  SQL_CREATE_TABLE_TOKEN_STORE,
200
204
  SQL_CREATE_INDEX_ONLINE_UNTIL,
201
205
  SQL_CREATE_INDEX_OWNER_AID,
206
+ SQL_CREATE_INDEX_NODE_STATUS,
202
207
  log_queries=log_queries,
203
208
  )
204
209
 
@@ -613,6 +618,61 @@ class SqliteLinkState(LinkState, SqliteMixin): # pylint: disable=R0904
613
618
  "deletion attempt."
614
619
  )
615
620
 
621
+ def activate_node(self, node_id: int, heartbeat_interval: float) -> bool:
622
+ """Activate the node with the specified `node_id`."""
623
+ with self.conn:
624
+ self._check_and_tag_offline_nodes([node_id])
625
+
626
+ # Only activate if the node is currently registered or offline
627
+ current_dt = now()
628
+ query = """
629
+ UPDATE node
630
+ SET status = ?,
631
+ last_activated_at = ?,
632
+ online_until = ?,
633
+ heartbeat_interval = ?
634
+ WHERE node_id = ? AND status in (?, ?)
635
+ RETURNING node_id
636
+ """
637
+ params = (
638
+ NodeStatus.ONLINE,
639
+ current_dt.isoformat(),
640
+ current_dt.timestamp() + HEARTBEAT_PATIENCE * heartbeat_interval,
641
+ heartbeat_interval,
642
+ uint64_to_int64(node_id),
643
+ NodeStatus.REGISTERED,
644
+ NodeStatus.OFFLINE,
645
+ )
646
+
647
+ row = self.conn.execute(query, params).fetchone()
648
+ return row is not None
649
+
650
+ def deactivate_node(self, node_id: int) -> bool:
651
+ """Deactivate the node with the specified `node_id`."""
652
+ with self.conn:
653
+ self._check_and_tag_offline_nodes([node_id])
654
+
655
+ # Only deactivate if the node is currently online
656
+ current_dt = now()
657
+ query = """
658
+ UPDATE node
659
+ SET status = ?,
660
+ last_deactivated_at = ?,
661
+ online_until = ?
662
+ WHERE node_id = ? AND status = ?
663
+ RETURNING node_id
664
+ """
665
+ params = (
666
+ NodeStatus.OFFLINE,
667
+ current_dt.isoformat(),
668
+ current_dt.timestamp(),
669
+ uint64_to_int64(node_id),
670
+ NodeStatus.ONLINE,
671
+ )
672
+
673
+ row = self.conn.execute(query, params).fetchone()
674
+ return row is not None
675
+
616
676
  def get_nodes(self, run_id: int) -> set[int]:
617
677
  """Retrieve all currently stored node IDs as a set.
618
678
 
@@ -638,6 +698,28 @@ class SqliteLinkState(LinkState, SqliteMixin): # pylint: disable=R0904
638
698
  node.node_id for node in self.get_node_info(statuses=[NodeStatus.ONLINE])
639
699
  }
640
700
 
701
+ def _check_and_tag_offline_nodes(
702
+ self, node_ids: Optional[list[int]] = None
703
+ ) -> None:
704
+ """Check and tag offline nodes."""
705
+ # strftime will convert POSIX timestamp to ISO format
706
+ query = """
707
+ UPDATE node SET status = ?,
708
+ last_deactivated_at =
709
+ strftime("%Y-%m-%dT%H:%M:%f+00:00", online_until, "unixepoch")
710
+ WHERE online_until <= ? AND status == ?
711
+ """
712
+ params = [
713
+ NodeStatus.OFFLINE,
714
+ now().timestamp(),
715
+ NodeStatus.ONLINE,
716
+ ]
717
+ if node_ids is not None:
718
+ placeholders = ",".join(["?"] * len(node_ids))
719
+ query += f" AND node_id IN ({placeholders})"
720
+ params.extend(uint64_to_int64(node_id) for node_id in node_ids)
721
+ self.conn.execute(query, params)
722
+
641
723
  def get_node_info(
642
724
  self,
643
725
  *,
@@ -646,29 +728,12 @@ class SqliteLinkState(LinkState, SqliteMixin): # pylint: disable=R0904
646
728
  statuses: Optional[Sequence[str]] = None,
647
729
  ) -> Sequence[NodeInfo]:
648
730
  """Retrieve information about nodes based on the specified filters."""
649
- if self.conn is None:
650
- raise AttributeError("LinkState is not initialized.")
651
-
652
731
  with self.conn:
653
- # Check and tag offline nodes
654
- current_dt = now()
655
- # strftime will convert POSIX timestamp to ISO format
656
- query = """
657
- UPDATE node SET status = ?,
658
- last_deactivated_at =
659
- strftime("%Y-%m-%dT%H:%M:%f+00:00", online_until, "unixepoch")
660
- WHERE online_until <= ? AND status == ?
661
- """
662
- params: list[Any] = [
663
- NodeStatus.OFFLINE,
664
- current_dt.timestamp(),
665
- NodeStatus.ONLINE,
666
- ]
667
- self.conn.execute(query, params)
732
+ self._check_and_tag_offline_nodes()
668
733
 
669
734
  # Build the WHERE clause based on provided filters
670
735
  conditions = []
671
- params = []
736
+ params: list[Any] = []
672
737
  if node_ids is not None:
673
738
  sint64_node_ids = [uint64_to_int64(node_id) for node_id in node_ids]
674
739
  placeholders = ",".join(["?"] * len(sint64_node_ids))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.23.0.dev20251027
3
+ Version: 1.23.0.dev20251029
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
@@ -9,7 +9,7 @@ flwr/cli/auth_plugin/__init__.py,sha256=qpebWV9uLpx72_J8yTVgT1DlH2Y9MK_RraDoTYEq
9
9
  flwr/cli/auth_plugin/auth_plugin.py,sha256=LK-DYGk8J85Mjsbc5BX9ueDVOOPcFSo9cKWJX25X-QI,3050
10
10
  flwr/cli/auth_plugin/noop_auth_plugin.py,sha256=KRyxoYtrzOWAIlSuXznli9gqL-rmHSG3zESmYSCQ_rg,2093
11
11
  flwr/cli/auth_plugin/oidc_cli_plugin.py,sha256=9Oyd23g-2vgsXhRQdqG9JNocPylGXZM4UVPBB6l0GXA,5147
12
- flwr/cli/build.py,sha256=hE54Q_eMdWLpVKSVC2aQaUxVaiUlWnAosGNvIPSEg6Y,7284
12
+ flwr/cli/build.py,sha256=G3pbe1IlwXZQPM8ZbzpvkhOwuhYQUxhkOF09VVUV3GI,9601
13
13
  flwr/cli/cli_account_auth_interceptor.py,sha256=o_D6-al3TgLRUAX2OZhzLlYF_LXDsK5dLkjbi082JNU,3131
14
14
  flwr/cli/config_utils.py,sha256=o75PJzgCTl9FdFo_I9OjCB02-ykK0VWZdhIAeR0A8QA,9130
15
15
  flwr/cli/constant.py,sha256=LtxufmhkEqNWQ9doWbbbkUKa12vN_RK_Of5u0So-GHA,1729
@@ -84,7 +84,7 @@ flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=g7SYiAJr6Uhwg4Zs
84
84
  flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl,sha256=yAJ9jL2q6U_XXYwwUT9fpIqIKFuQR_Kgg82GpWfQ5J8,1661
85
85
  flwr/cli/pull.py,sha256=sT3-f2zf7JcXfB-pHWLXmENrOzJeUDBoqK3oruJxzao,3352
86
86
  flwr/cli/run/__init__.py,sha256=RPyB7KbYTFl6YRiilCch6oezxrLQrl1kijV7BMGkLbA,790
87
- flwr/cli/run/run.py,sha256=f5ysmBytcme8E7feroCtvpLe3kEebSFV42dcqoSFzzY,8165
87
+ flwr/cli/run/run.py,sha256=2QYhD4o0CfChN68eV0MFZULP3G1DoQInNKrWsupu0Dw,8386
88
88
  flwr/cli/stop.py,sha256=W7ynTYLm0-_1nC5Il4IaZTji6A3GCCm_0R-HQUudAsI,4988
89
89
  flwr/cli/supernode/__init__.py,sha256=DBkjoPo2hS2Y-ghJxwLbrAbCQFBgD82_Itl2_892UBo,917
90
90
  flwr/cli/supernode/ls.py,sha256=OVEs9zPSomxxiwCg1Jz8AN5MkZJDf3xAE-lxCG22zyE,8640
@@ -98,7 +98,7 @@ flwr/client/grpc_adapter_client/__init__.py,sha256=RQWP5mFPROLHKgombiRvPXVWSoVrQ
98
98
  flwr/client/grpc_adapter_client/connection.py,sha256=JGv02EjSOAG1E5BRUD4lwXc1LLiYJ0OhInvp31qx1cU,4404
99
99
  flwr/client/grpc_rere_client/__init__.py,sha256=i7iS0Lt8B7q0E2L72e4F_YrKm6ClRKnd71PNA6PW2O0,752
100
100
  flwr/client/grpc_rere_client/connection.py,sha256=3_CI7wx5ZrkGrVCXjDKiUGX9aJP9Zm9yl4iqSBAmH3U,13100
101
- flwr/client/grpc_rere_client/grpc_adapter.py,sha256=dLGB5GriszAmtgvuFGuz_F7rIwpzLfDxhJ7T3Un-Ce0,6694
101
+ flwr/client/grpc_rere_client/grpc_adapter.py,sha256=YwsZOvFgCd1JdiHnl1Cc18vKOiGwWSSJ_9-ZXwlGZvs,7900
102
102
  flwr/client/grpc_rere_client/node_auth_client_interceptor.py,sha256=EdTyb5ThFrpkeyXy9_nTKH7E9GnfAdXjcNZ_-uxt1AA,2410
103
103
  flwr/client/message_handler/__init__.py,sha256=0lyljDVqre3WljiZbPcwCCf8GiIaSVI_yo_ylEyPwSE,719
104
104
  flwr/client/message_handler/message_handler.py,sha256=X9SXX6et97Lw9_DGD93HKsEBGNjXClcFgc_5aLK0oiU,6541
@@ -126,7 +126,7 @@ flwr/common/__init__.py,sha256=5GCLVk399Az_rTJHNticRlL0Sl_oPw_j5_LuFKfX7-M,4171
126
126
  flwr/common/address.py,sha256=9JucdTwlc-jpeJkRKeUboZoacUtErwSVtnDR9kAtLqE,4119
127
127
  flwr/common/args.py,sha256=Nq2u4yePbkSY0CWFamn0hZY6Rms8G1xYDeDGIcLIITE,5849
128
128
  flwr/common/config.py,sha256=glcZDjco-amw1YfQcYTFJ4S1pt9APoexT-mf1QscuHs,13960
129
- flwr/common/constant.py,sha256=y9U6LdgMzNYe-LGTjooGn0QJj5MVTlWjbriE1l5rkag,9898
129
+ flwr/common/constant.py,sha256=EjVoFZZgkxREzd312A2K4LlNk8H27rU4hWGW-CZ9qCI,10145
130
130
  flwr/common/context.py,sha256=Be8obQR_OvEDy1OmshuUKxGRQ7Qx89mf5F4xlhkR10s,2407
131
131
  flwr/common/date.py,sha256=1ZT2cRSpC2DJqprOVTLXYCR_O2_OZR0zXO_brJ3LqWc,1554
132
132
  flwr/common/differential_privacy.py,sha256=FdlpdpPl_H_2HJa8CQM1iCUGBBQ5Dc8CzxmHERM-EoE,6148
@@ -203,10 +203,10 @@ flwr/proto/fab_pb2.py,sha256=AQAUJmTt31Kq-lJQid3CJpQPrply2-OA_aSHokpVF84,2070
203
203
  flwr/proto/fab_pb2.pyi,sha256=GOxeDi-UYzQVwIEzRk9YkzkriowmNdibZu3jMMtBPFo,3273
204
204
  flwr/proto/fab_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
205
205
  flwr/proto/fab_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
206
- flwr/proto/fleet_pb2.py,sha256=xGnNGmBbPds6LeB34HN8_vy4U1oW25-w-r-C6xNpoRo,5190
207
- flwr/proto/fleet_pb2.pyi,sha256=btn0ertRlY5LenpN-YoiqA4X8NQgbkZsAJZQWN8Tia0,7939
208
- flwr/proto/fleet_pb2_grpc.py,sha256=NmzrDYxyM3MQNh3vwYczQNuFimZz3prU6ke3E-fKk_g,17539
209
- flwr/proto/fleet_pb2_grpc.pyi,sha256=PDERhzOrBCMAytTLS65Qck8A45bTIYni7Lotq6_I0sM,4721
206
+ flwr/proto/fleet_pb2.py,sha256=FyQJ-FCsYJLwQZeYrs_p6Y_OgA9jPoxGHyIvWeukXxU,7171
207
+ flwr/proto/fleet_pb2.pyi,sha256=-cKglysTm0FPkAqdD2cKzfxFhb1rP_z5aOD5RSPrFxU,11209
208
+ flwr/proto/fleet_pb2_grpc.py,sha256=ss_fFtTJuVSzYLxWsW5Fn6XfUBnJIKV7BTBX5vyhPMY,24083
209
+ flwr/proto/fleet_pb2_grpc.pyi,sha256=WJIV7EmoePxY6CaYF1cj3oZ2ss6E1pt7Zs5C6ehz69c,6461
210
210
  flwr/proto/grpcadapter_pb2.py,sha256=PJ8DtfeV29g_y4Z3aNZlSZocLqSxeLmTsYCdOZDYCiE,1843
211
211
  flwr/proto/grpcadapter_pb2.pyi,sha256=AR77gDsF6f8zqSIQp3877DUd7S8lP95lFak5Ir_WPkw,1716
212
212
  flwr/proto/grpcadapter_pb2_grpc.py,sha256=rRNuNES5nBugUZWfeA8oAy8dMHgzqU_PF1srTseo3b8,2634
@@ -298,29 +298,29 @@ flwr/server/strategy/strategy.py,sha256=n4r52i5gK4KGToZvcJUeWuEif1tuI0HZUT3YJPTC
298
298
  flwr/server/superlink/__init__.py,sha256=GNSuJ4-N6Z8wun2iZNlXqENt5beUyzC0Gi_tN396bbM,707
299
299
  flwr/server/superlink/fleet/__init__.py,sha256=Uiwr33yfW_eL-pEfj80c_JUhIKRkCPsN1JSs2v4aglU,711
300
300
  flwr/server/superlink/fleet/grpc_adapter/__init__.py,sha256=fUu1V63YrzjxAOZnBJx99WjuD4Mro7dJIFH-1V4NLV8,742
301
- flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py,sha256=hHTQ3ryI31TIGN4v9zkYNf8tx3hsiYHiovmsq3PCB6c,5018
301
+ flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py,sha256=zFWNbVnT-HMHJiZO154ciaT2GeA8TcFpwEJuNI793eU,5879
302
302
  flwr/server/superlink/fleet/grpc_bidi/__init__.py,sha256=dOM49q1b9MrtUr5jldjEnQ38NhcUyYs-zC3gsJb1TtI,735
303
303
  flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py,sha256=UKEp-3YBaTvNt7vKZW7KLgK5xsAiO7jxU-omG7CaO_s,6021
304
304
  flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py,sha256=KouR9PUcrPmMtoLooF4O9SRAwIvfiroo8mPmqUc2EZc,6485
305
305
  flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py,sha256=iSf0mbBAlig7G6subQwBSVjcUCgSihONKdZ1RmQPTOk,4887
306
306
  flwr/server/superlink/fleet/grpc_bidi/grpc_server.py,sha256=OsS-6GgCIzMMZDVu5Y-OKjynHVUrpdc_5OrtuB-IbU0,5174
307
307
  flwr/server/superlink/fleet/grpc_rere/__init__.py,sha256=ahDJJ1e-lDxBpeBMgPk7YZt2wB38_QltcpOC0gLbpFs,758
308
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=V9CMyaYVc1t5Wt_63H5zcMbs8iC8HD-V31TXLlCPts4,11672
308
+ flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=0HwtOgCuQ1x8YCZXMFN6a2Y7agR4TR5e6rruBuxqqrI,13620
309
309
  flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py,sha256=UWeFQNBW2pGBRVN36HodHcv7bKTgMmdToh96Lhqip1M,5411
310
310
  flwr/server/superlink/fleet/message_handler/__init__.py,sha256=fHsRV0KvJ8HtgSA4_YBsEzuhJLjO8p6xx4aCY2oE1p4,731
311
311
  flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=GYveEXgKRlyrKRUr2H6kjWPx_g4-fnATrMdJD2G4Gaw,8762
312
312
  flwr/server/superlink/fleet/rest_rere/__init__.py,sha256=Lzc93nA7tDqoy-zRUaPG316oqFiZX1HUCL5ELaXY_xw,735
313
- flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=mxWKwGpgHPqd7cGFqd2ASnR-KZduIzLfT-d2yiNCqQ0,9257
313
+ flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=HzLx_3sY2_EXBLzLA_ZvKgZrgFDzIh0wesDfLrqyxvU,9875
314
314
  flwr/server/superlink/fleet/vce/__init__.py,sha256=XOKbAWOzlCqEOQ3M2cBYkH7HKA7PxlbCJMunt-ty-DY,784
315
315
  flwr/server/superlink/fleet/vce/backend/__init__.py,sha256=PPH89Yqd1XKm-sRJN6R0WQlKT_b4v54Kzl2yzHAFzM8,1437
316
316
  flwr/server/superlink/fleet/vce/backend/backend.py,sha256=cSrHZ5SjCCvy4vI0pgsyjtx3cDMuMQve8KcKkK-dWWo,2196
317
317
  flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=cBZYTmfiAsb1HmVUmOQXYLU-UJmJTFWkj1wW4RYRDuc,7218
318
318
  flwr/server/superlink/fleet/vce/vce_api.py,sha256=sgsAx7dgIADA-Ae71s5dwoPY0bw3-qA7RukJgnh8pgc,13389
319
319
  flwr/server/superlink/linkstate/__init__.py,sha256=OtsgvDTnZLU3k0sUbkHbqoVwW6ql2FDmb6uT6DbNkZo,1064
320
- flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=9JBJSWh7TAEf7WFcpdn03rL0tLrroVUPZcyNJd8Qz88,29997
321
- flwr/server/superlink/linkstate/linkstate.py,sha256=JKgVEPnH2T-nixW3LHp8jR3g4ITAZYNwEoDIWZaUYmQ,14701
320
+ flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=STJs4CNgdRknGFvreCdumBSDfUxqW8X0hpCun1wcROM,31829
321
+ flwr/server/superlink/linkstate/linkstate.py,sha256=DabTgFFissJhT_MCPiluz5eFrS3c412q8FnRqQrAidY,15945
322
322
  flwr/server/superlink/linkstate/linkstate_factory.py,sha256=KVBpc8UxVrJCQ7IkOjVZVWb-kqWx08AGVi7qXzZS190,2126
323
- flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=vmD74L8fphb0xIhArQUg1p7oy_k6nEzxXIZHCSxFxh0,45219
323
+ flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=5KJnrqDz1bNphLhJI9iZz2_mrbl1_DsTOSbwfncsE1E,47528
324
324
  flwr/server/superlink/linkstate/utils.py,sha256=ZtyqSo4HzGrHXW3Wn_4irYMpIiq4onNI2XCIVOOJmJM,13971
325
325
  flwr/server/superlink/serverappio/__init__.py,sha256=Fy4zJuoccZe5mZSEIpOmQvU6YeXFBa1M4eZuXXmJcn8,717
326
326
  flwr/server/superlink/serverappio/serverappio_grpc.py,sha256=-I7kBbr4w4ZVYwBZoAIle-xHKthFnZrsVfxa6WR8uxA,2310
@@ -433,7 +433,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
433
433
  flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
434
434
  flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=ZvKosLV7GN1_fOF-tOmhqFQysYQywCysRc-m23DVIWA,10265
435
435
  flwr/supernode/start_client_internal.py,sha256=wKqh9-_rQYi7JFKpYBLRiUeq9YJUSyUd9b-SnVnuvwI,21567
436
- flwr_nightly-1.23.0.dev20251027.dist-info/METADATA,sha256=PvUk4HrZo9-Ztc5hxec-ihDiAaIq8QFxdrZkid0eNe4,14559
437
- flwr_nightly-1.23.0.dev20251027.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
438
- flwr_nightly-1.23.0.dev20251027.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
439
- flwr_nightly-1.23.0.dev20251027.dist-info/RECORD,,
436
+ flwr_nightly-1.23.0.dev20251029.dist-info/METADATA,sha256=IbVE7qYkOpvhbjaQ8hYXUx3el8wwZN8UQKbeTKeKrjE,14559
437
+ flwr_nightly-1.23.0.dev20251029.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
438
+ flwr_nightly-1.23.0.dev20251029.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
439
+ flwr_nightly-1.23.0.dev20251029.dist-info/RECORD,,