flwr-nightly 1.21.0.dev20250806__py3-none-any.whl → 1.21.0.dev20250808__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.
@@ -686,12 +686,12 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
686
686
  latest_timestamp = run.logs[-1][0] if index < len(run.logs) else 0.0
687
687
  return "".join(log for _, log in run.logs[index:]), latest_timestamp
688
688
 
689
- def create_token(self, run_id: int) -> str:
689
+ def create_token(self, run_id: int) -> Optional[str]:
690
690
  """Create a token for the given run ID."""
691
691
  token = secrets.token_hex(FLWR_APP_TOKEN_LENGTH) # Generate a random token
692
692
  with self.lock_token_store:
693
693
  if run_id in self.token_store:
694
- raise ValueError("Token already created for this run ID")
694
+ return None # Token already created for this run ID
695
695
  self.token_store[run_id] = token
696
696
  self.token_to_run_id[token] = run_id
697
697
  return token
@@ -1148,7 +1148,7 @@ class SqliteLinkState(LinkState): # pylint: disable=R0904
1148
1148
 
1149
1149
  return message_ins
1150
1150
 
1151
- def create_token(self, run_id: int) -> str:
1151
+ def create_token(self, run_id: int) -> Optional[str]:
1152
1152
  """Create a token for the given run ID."""
1153
1153
  token = secrets.token_hex(FLWR_APP_TOKEN_LENGTH) # Generate a random token
1154
1154
  query = "INSERT INTO token_store (run_id, token) VALUES (:run_id, :token);"
@@ -1156,7 +1156,7 @@ class SqliteLinkState(LinkState): # pylint: disable=R0904
1156
1156
  try:
1157
1157
  self.query(query, data)
1158
1158
  except sqlite3.IntegrityError:
1159
- raise ValueError("Token already created for this run ID") from None
1159
+ return None # Token already created for this run ID
1160
1160
  return token
1161
1161
 
1162
1162
  def verify_token(self, run_id: int, token: str) -> bool:
@@ -114,21 +114,35 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
114
114
  context: grpc.ServicerContext,
115
115
  ) -> ListAppsToLaunchResponse:
116
116
  """Get run IDs with pending messages."""
117
- log(DEBUG, "ClientAppIo.ListAppsToLaunch")
117
+ log(DEBUG, "ServerAppIoServicer.ListAppsToLaunch")
118
118
 
119
- context.abort(
120
- grpc.StatusCode.UNIMPLEMENTED, "ListAppsToLaunch is not implemented"
121
- )
122
- raise NotImplementedError
119
+ # Initialize state connection
120
+ state = self.state_factory.state()
121
+
122
+ # Get IDs of runs in pending status
123
+ run_ids = state.get_run_ids(flwr_aid=None)
124
+ pending_run_ids = []
125
+ for run_id, status in state.get_run_status(run_ids).items():
126
+ if status.status == Status.PENDING:
127
+ pending_run_ids.append(run_id)
128
+
129
+ # Return run IDs
130
+ return ListAppsToLaunchResponse(run_ids=pending_run_ids)
123
131
 
124
132
  def RequestToken(
125
133
  self, request: RequestTokenRequest, context: grpc.ServicerContext
126
134
  ) -> RequestTokenResponse:
127
135
  """Request token."""
128
- log(DEBUG, "ClientAppIo.RequestToken")
136
+ log(DEBUG, "ServerAppIoServicer.RequestToken")
137
+
138
+ # Initialize state connection
139
+ state = self.state_factory.state()
140
+
141
+ # Attempt to create a token for the provided run ID
142
+ token = state.create_token(request.run_id)
129
143
 
130
- context.abort(grpc.StatusCode.UNIMPLEMENTED, "RequestToken is not implemented")
131
- raise NotImplementedError
144
+ # Return the token
145
+ return RequestTokenResponse(token=token or "")
132
146
 
133
147
  def GetNodes(
134
148
  self, request: GetNodesRequest, context: grpc.ServicerContext
@@ -23,7 +23,7 @@ class CoreState(ABC):
23
23
  """Abstract base class for core state."""
24
24
 
25
25
  @abstractmethod
26
- def create_token(self, run_id: int) -> str:
26
+ def create_token(self, run_id: int) -> Optional[str]:
27
27
  """Create a token for the given run ID.
28
28
 
29
29
  Parameters
@@ -34,7 +34,8 @@ class CoreState(ABC):
34
34
  Returns
35
35
  -------
36
36
  str
37
- A unique token associated with the run ID.
37
+ The newly generated token if one does not already exist
38
+ for the given run ID, otherwise None.
38
39
  """
39
40
 
40
41
  @abstractmethod
@@ -12,11 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Flower App Scheduler."""
16
-
17
-
18
- from .plugin import SchedulerPlugin
19
-
20
- __all__ = [
21
- "SchedulerPlugin",
22
- ]
15
+ """Flower SuperExec."""
@@ -12,11 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Flower ClientApp Scheduler."""
15
+ """Flower SuperExec plugins."""
16
16
 
17
17
 
18
- from .simple_clientapp_scheduler_plugin import SimpleClientAppSchedulerPlugin
18
+ from .clientapp_exec_plugin import ClientAppExecPlugin
19
+ from .exec_plugin import ExecPlugin
19
20
 
20
21
  __all__ = [
21
- "SimpleClientAppSchedulerPlugin",
22
+ "ClientAppExecPlugin",
23
+ "ExecPlugin",
22
24
  ]
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Simple Flower ClientApp Scheduler plugin."""
15
+ """Simple Flower SuperExec plugin for ClientApp."""
16
16
 
17
17
 
18
18
  import os
@@ -20,11 +20,11 @@ import subprocess
20
20
  from collections.abc import Sequence
21
21
  from typing import Optional
22
22
 
23
- from flwr.supercore.scheduler import SchedulerPlugin
23
+ from .exec_plugin import ExecPlugin
24
24
 
25
25
 
26
- class SimpleClientAppSchedulerPlugin(SchedulerPlugin):
27
- """Simple Flower ClientApp Scheduler plugin.
26
+ class ClientAppExecPlugin(ExecPlugin):
27
+ """Simple Flower SuperExec plugin for ClientApp.
28
28
 
29
29
  The plugin always selects the first candidate run ID.
30
30
  """
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Abstract base class SchedulerPlugin."""
15
+ """Abstract base class ExecPlugin."""
16
16
 
17
17
 
18
18
  from abc import ABC, abstractmethod
@@ -22,8 +22,8 @@ from typing import Callable, Optional
22
22
  from flwr.common.typing import Run
23
23
 
24
24
 
25
- class SchedulerPlugin(ABC):
26
- """Abstract base class for Scheduler plugins."""
25
+ class ExecPlugin(ABC):
26
+ """Abstract base class for SuperExec plugins."""
27
27
 
28
28
  def __init__(
29
29
  self,
@@ -59,7 +59,7 @@ class SchedulerPlugin(ABC):
59
59
 
60
60
  This method starts the application process using the given `token`.
61
61
  The `run_id` is used solely for bookkeeping purposes, allowing any
62
- scheduler implementation to associate this launch with a specific run.
62
+ plugin implementation to associate this launch with a specific run.
63
63
 
64
64
  Parameters
65
65
  ----------
@@ -171,12 +171,12 @@ class InMemoryNodeState(NodeState): # pylint: disable=too-many-instance-attribu
171
171
  ret -= set(self.token_store.keys())
172
172
  return list(ret)
173
173
 
174
- def create_token(self, run_id: int) -> str:
174
+ def create_token(self, run_id: int) -> Optional[str]:
175
175
  """Create a token for the given run ID."""
176
176
  token = secrets.token_hex(FLWR_APP_TOKEN_LENGTH) # Generate a random token
177
177
  with self.lock_token_store:
178
178
  if run_id in self.token_store:
179
- raise ValueError("Token already created for this run ID")
179
+ return None # Token already created for this run ID
180
180
  self.token_store[run_id] = token
181
181
  self.token_to_run_id[token] = run_id
182
182
  return token
@@ -107,15 +107,10 @@ class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
107
107
  state = self.state_factory.state()
108
108
 
109
109
  # Attempt to create a token for the provided run ID
110
- try:
111
- token = state.create_token(request.run_id)
112
- except ValueError:
113
- # Return an empty token if A token already exists for this run ID,
114
- # indicating the run is in progress
115
- return RequestTokenResponse(token="")
110
+ token = state.create_token(request.run_id)
116
111
 
117
112
  # Return the token
118
- return RequestTokenResponse(token=token)
113
+ return RequestTokenResponse(token=token or "")
119
114
 
120
115
  def GetRun(
121
116
  self, request: GetRunRequest, context: grpc.ServicerContext
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.21.0.dev20250806
3
+ Version: 1.21.0.dev20250808
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
@@ -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=jm5ZB6kePnikMEIN841bHedoC8Cjnve5JI2v6Wy8v6E,27886
301
+ flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=eNjjQp6dJ_Qz54fYeOZ9XFebbB_k9syhBB6N2rXRTsA,27891
302
302
  flwr/server/superlink/linkstate/linkstate.py,sha256=TCLM9wZa2XGHs55B3LP9j5-WtUPhBjOUdMKQJELG2oY,13287
303
303
  flwr/server/superlink/linkstate/linkstate_factory.py,sha256=8RlosqSpKOoD_vhUUQPY0jtE3A84GeF96Z7sWNkRRcA,2069
304
- flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=ROAdb_uvaCsJa-AJbczbPFOpdaFiof2Y1s1fSBO6YUo,45508
304
+ flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=NIJ1BDcj54TUpNaeb23af38wQE-TM6rnYVMJncJVKQ0,45503
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=zcvzDhCAnlFxAwCiJUHNm6IE7-rk5jeZqSmPgjEY3AU,2307
308
- flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=DmYfjHQLya7LD4rLBLhDCdH9XTBgV8X790D3tdwHZpk,19096
308
+ flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=hNTpzbBAUBlMB-PgPWW-DlVqfsmM_whXsXQeC8ZpNG8,19579
309
309
  flwr/server/superlink/simulation/__init__.py,sha256=Ry8DrNaZCMcQXvUc4FoCN2m3dvUQgWjasfp015o3Ec4,718
310
310
  flwr/server/superlink/simulation/simulationio_grpc.py,sha256=VqWKxjpd4bCgPFKsgtIZPk9YcG0kc1EEmr5k20EKty4,2205
311
311
  flwr/server/superlink/simulation/simulationio_servicer.py,sha256=m1T1zvEn81jlfx9hVTqmeWxAu6APCS2YW8l5O0OQvhU,7724
@@ -332,7 +332,7 @@ flwr/simulation/run_simulation.py,sha256=-sp3dNZcp7MCAH0BlmZpVcFAGvozRdYXRdDYcH_
332
332
  flwr/simulation/simulationio_connection.py,sha256=mzS1C6EEREwQDPceDo30anAasmTDLb9qqV2tXlBhOUA,3494
333
333
  flwr/supercore/__init__.py,sha256=pqkFoow_E6UhbBlhmoD1gmTH-33yJRhBsIZqxRPFZ7U,755
334
334
  flwr/supercore/corestate/__init__.py,sha256=Vau6-L_JG5QzNqtCTa9xCKGGljc09wY8avZmIjSJemg,774
335
- flwr/supercore/corestate/corestate.py,sha256=vfZxZ6ddpg5ej3BJCJdaumQImElXG-lIaj-942xdT90,2255
335
+ flwr/supercore/corestate/corestate.py,sha256=rDAWWeG5DcpCyQso9Z3RhwL4zr2IroPlRMcDzqoSu8s,2328
336
336
  flwr/supercore/ffs/__init__.py,sha256=U3KXwG_SplEvchat27K0LYPoPHzh-cwwT_NHsGlYMt8,908
337
337
  flwr/supercore/ffs/disk_ffs.py,sha256=c5VywSaRnq3XM_zuJptNtsF2HFwsRK0pvBd5-5CNONs,3272
338
338
  flwr/supercore/ffs/ffs.py,sha256=6w7wy71i7tbuJwqEgdeCa49JejXMEof3jujURN_R7Rg,2395
@@ -346,8 +346,10 @@ flwr/supercore/object_store/in_memory_object_store.py,sha256=CGY43syxDGrUPcdOzRH
346
346
  flwr/supercore/object_store/object_store.py,sha256=J-rI3X7ET-F6dqOyM-UfHKCCQtPJ_EnYW62H_1txts0,5252
347
347
  flwr/supercore/object_store/object_store_factory.py,sha256=QVwE2ywi7vsj2iKfvWWnNw3N_I7Rz91NUt2RpcbJ7iM,1527
348
348
  flwr/supercore/object_store/utils.py,sha256=DcPbrb9PenloAPoQRiKiXX9DrDfpXcSyY0cZpgn4PeQ,1680
349
- flwr/supercore/scheduler/__init__.py,sha256=E4GviiNJoZKz1dOao8ZGRHExsiM23GtOrkpMrTHy3n8,787
350
- flwr/supercore/scheduler/plugin.py,sha256=kIv0JUrHP-ghrcGT-pbporL9A2mUz8PxASw6KgxCRv8,2460
349
+ flwr/supercore/superexec/__init__.py,sha256=XKX208hZ6a9gZ4KT9kMqfpCtp_8VGxekzKFfHSu2esQ,707
350
+ flwr/supercore/superexec/plugin/__init__.py,sha256=OH5WYxZssOUzOVya3na4yHH0bRwtYmnottUreJT9R20,868
351
+ flwr/supercore/superexec/plugin/clientapp_exec_plugin.py,sha256=qX7vcB2n4crlfTTHKNqV0jHBmk8DiCIRuGDwLGAhP7g,1975
352
+ flwr/supercore/superexec/plugin/exec_plugin.py,sha256=w3jmtxdv7ov_EdAgifKcm4q8nV39e2Xna4sNjqClwOM,2447
351
353
  flwr/supercore/utils.py,sha256=ebuHMbeA8eXisX0oMPqBK3hk7uVnIE_yiqWVz8YbkpQ,1324
352
354
  flwr/superexec/__init__.py,sha256=YFqER0IJc1XEWfsX6AxZ9LSRq0sawPYrNYki-brvTIc,715
353
355
  flwr/superexec/deployment.py,sha256=CEgWfkN_lH6Vci03RjwKLENw2z6kxNvUdVEErPbqYDY,830
@@ -370,18 +372,16 @@ flwr/supernode/cli/__init__.py,sha256=JuEMr0-s9zv-PEWKuLB9tj1ocNfroSyNJ-oyv7ati9
370
372
  flwr/supernode/cli/flower_supernode.py,sha256=fAkk9zGhoP8Sv05EkdXRiCtirTAzWkSZBqRoaDdgflk,8529
371
373
  flwr/supernode/cli/flwr_clientapp.py,sha256=zaro6BoUEmfKIPQYuyJ9oR4rrHSS3bufhEqxcTo5VZU,3153
372
374
  flwr/supernode/nodestate/__init__.py,sha256=CyLLObbmmVgfRO88UCM0VMait1dL57mUauUDfuSHsbU,976
373
- flwr/supernode/nodestate/in_memory_nodestate.py,sha256=LF3AbaW0bcZHY5yKWwUJSU2RZbMynt-YjFysGqvTOQY,7338
375
+ flwr/supernode/nodestate/in_memory_nodestate.py,sha256=rr_tg7YXhf_seYFipSB59TAfheKPratx3rrvHUOJ80g,7343
374
376
  flwr/supernode/nodestate/nodestate.py,sha256=jCOewZyctecMxsM0-_-pQwef9P3O5QjnKCgCGyx2PK4,5047
375
377
  flwr/supernode/nodestate/nodestate_factory.py,sha256=UYTDCcwK_baHUmkzkJDxL0UEqvtTfOMlQRrROMCd0Xo,1430
376
378
  flwr/supernode/runtime/__init__.py,sha256=JQdqd2EMTn-ORMeTvewYYh52ls0YKP68jrps1qioxu4,718
377
379
  flwr/supernode/runtime/run_clientapp.py,sha256=efocWcTe2ufkhe4BzMGgxe0COq9aDyJ6HzXwQ8ZaIAU,10551
378
- flwr/supernode/scheduler/__init__.py,sha256=nQLi5ROVCMz8ii_WsZn4MAqKHXI40Eb3tq5-9zZbmpg,850
379
- flwr/supernode/scheduler/simple_clientapp_scheduler_plugin.py,sha256=nnNuKhelrAEGCnWZ3aAkqJrhPu7xlVQ-oO1Eih9shTU,2000
380
380
  flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca8gxdEo,717
381
381
  flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
382
- flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=Egp8V_Z3k9wWJUhXEXVWyf-g9iZ_lI6VcoKQTtG9uQg,10454
382
+ flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=nIHRu38EWK-rpNOkcgBRAAKwYQQWFeCwu0lkO7OPZGQ,10239
383
383
  flwr/supernode/start_client_internal.py,sha256=iqJR8WbCW-8RQIRNwARZYoxhnlaAo5KnluCOEfRoLWM,21020
384
- flwr_nightly-1.21.0.dev20250806.dist-info/METADATA,sha256=Y6qSCklbNFCeLm17NenNYbX8me-uZz3aY8GZ4BxDv7U,15966
385
- flwr_nightly-1.21.0.dev20250806.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
386
- flwr_nightly-1.21.0.dev20250806.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
387
- flwr_nightly-1.21.0.dev20250806.dist-info/RECORD,,
384
+ flwr_nightly-1.21.0.dev20250808.dist-info/METADATA,sha256=Vum_8HABoCD2VNWP0z2uHa-Zq8mrknTMJllovrrQPF0,15966
385
+ flwr_nightly-1.21.0.dev20250808.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
386
+ flwr_nightly-1.21.0.dev20250808.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
387
+ flwr_nightly-1.21.0.dev20250808.dist-info/RECORD,,