flwr-nightly 1.19.0.dev20250521__py3-none-any.whl → 1.19.0.dev20250523__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.
Files changed (28) hide show
  1. flwr/client/grpc_adapter_client/connection.py +4 -4
  2. flwr/client/grpc_rere_client/connection.py +4 -4
  3. flwr/client/rest_client/connection.py +4 -4
  4. flwr/common/inflatable.py +23 -0
  5. flwr/common/inflatable_grpc_utils.py +2 -0
  6. flwr/compat/client/app.py +2 -2
  7. flwr/proto/run_pb2.py +19 -27
  8. flwr/proto/run_pb2.pyi +0 -51
  9. flwr/proto/serverappio_pb2.py +2 -2
  10. flwr/proto/serverappio_pb2_grpc.py +0 -34
  11. flwr/proto/serverappio_pb2_grpc.pyi +0 -13
  12. flwr/server/app.py +12 -1
  13. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +6 -1
  14. flwr/server/superlink/serverappio/serverappio_grpc.py +3 -0
  15. flwr/server/superlink/serverappio/serverappio_servicer.py +7 -32
  16. flwr/supercore/object_store/__init__.py +23 -0
  17. flwr/supercore/object_store/in_memory_object_store.py +65 -0
  18. flwr/supercore/object_store/object_store.py +86 -0
  19. flwr/supercore/object_store/object_store_factory.py +44 -0
  20. flwr/{client/supernode → supernode/cli}/__init__.py +3 -5
  21. flwr/{client/supernode/app.py → supernode/cli/flower_supernode.py} +2 -10
  22. flwr/{client → supernode}/start_client_internal.py +179 -301
  23. {flwr_nightly-1.19.0.dev20250521.dist-info → flwr_nightly-1.19.0.dev20250523.dist-info}/METADATA +1 -1
  24. {flwr_nightly-1.19.0.dev20250521.dist-info → flwr_nightly-1.19.0.dev20250523.dist-info}/RECORD +28 -24
  25. {flwr_nightly-1.19.0.dev20250521.dist-info → flwr_nightly-1.19.0.dev20250523.dist-info}/entry_points.txt +1 -1
  26. /flwr/{client → compat/client}/grpc_client/__init__.py +0 -0
  27. /flwr/{client → compat/client}/grpc_client/connection.py +0 -0
  28. {flwr_nightly-1.19.0.dev20250521.dist-info → flwr_nightly-1.19.0.dev20250523.dist-info}/WHEEL +0 -0
@@ -0,0 +1,65 @@
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Flower in-memory ObjectStore implementation."""
16
+
17
+
18
+ from typing import Optional
19
+
20
+ from flwr.common.inflatable import get_object_id, is_valid_sha256_hash
21
+
22
+ from .object_store import ObjectStore
23
+
24
+
25
+ class InMemoryObjectStore(ObjectStore):
26
+ """In-memory implementation of the ObjectStore interface."""
27
+
28
+ def __init__(self, verify: bool = True) -> None:
29
+ self.verify = verify
30
+ self.store: dict[str, bytes] = {}
31
+
32
+ def put(self, object_id: str, object_content: bytes) -> None:
33
+ """Put an object into the store."""
34
+ # Verify object ID format (must be a valid sha256 hash)
35
+ if not is_valid_sha256_hash(object_id):
36
+ raise ValueError(f"Invalid object ID format: {object_id}")
37
+
38
+ # Verify object_id and object_content match
39
+ if self.verify:
40
+ object_id_from_content = get_object_id(object_content)
41
+ if object_id != object_id_from_content:
42
+ raise ValueError(f"Object ID {object_id} does not match content hash")
43
+
44
+ # Return if object is already present in the store
45
+ if object_id in self.store:
46
+ return
47
+
48
+ self.store[object_id] = object_content
49
+
50
+ def get(self, object_id: str) -> Optional[bytes]:
51
+ """Get an object from the store."""
52
+ return self.store.get(object_id)
53
+
54
+ def delete(self, object_id: str) -> None:
55
+ """Delete an object from the store."""
56
+ if object_id in self.store:
57
+ del self.store[object_id]
58
+
59
+ def clear(self) -> None:
60
+ """Clear the store."""
61
+ self.store.clear()
62
+
63
+ def __contains__(self, object_id: str) -> bool:
64
+ """Check if an object_id is in the store."""
65
+ return object_id in self.store
@@ -0,0 +1,86 @@
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Flower abstract ObjectStore definition."""
16
+
17
+
18
+ import abc
19
+ from typing import Optional
20
+
21
+
22
+ class ObjectStore(abc.ABC):
23
+ """Abstract base class for `ObjectStore` implementations.
24
+
25
+ This class defines the interface for an object store that can store, retrieve, and
26
+ delete objects identified by object IDs.
27
+ """
28
+
29
+ @abc.abstractmethod
30
+ def put(self, object_id: str, object_content: bytes) -> None:
31
+ """Put an object into the store.
32
+
33
+ Parameters
34
+ ----------
35
+ object_id : str
36
+ The object_id under which to store the object.
37
+ object_content : bytes
38
+ The deflated object to store.
39
+ """
40
+
41
+ @abc.abstractmethod
42
+ def get(self, object_id: str) -> Optional[bytes]:
43
+ """Get an object from the store.
44
+
45
+ Parameters
46
+ ----------
47
+ object_id : str
48
+ The object_id under which the object is stored.
49
+
50
+ Returns
51
+ -------
52
+ bytes
53
+ The object stored under the given object_id.
54
+ """
55
+
56
+ @abc.abstractmethod
57
+ def delete(self, object_id: str) -> None:
58
+ """Delete an object from the store.
59
+
60
+ Parameters
61
+ ----------
62
+ object_id : str
63
+ The object_id under which the object is stored.
64
+ """
65
+
66
+ @abc.abstractmethod
67
+ def clear(self) -> None:
68
+ """Clear the store.
69
+
70
+ This method should remove all objects from the store.
71
+ """
72
+
73
+ @abc.abstractmethod
74
+ def __contains__(self, object_id: str) -> bool:
75
+ """Check if an object_id is in the store.
76
+
77
+ Parameters
78
+ ----------
79
+ object_id : str
80
+ The object_id to check.
81
+
82
+ Returns
83
+ -------
84
+ bool
85
+ True if the object_id is in the store, False otherwise.
86
+ """
@@ -0,0 +1,44 @@
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Factory class that creates ObjectStore instances."""
16
+
17
+
18
+ from logging import DEBUG
19
+ from typing import Optional
20
+
21
+ from flwr.common.logger import log
22
+
23
+ from .in_memory_object_store import InMemoryObjectStore
24
+ from .object_store import ObjectStore
25
+
26
+
27
+ class ObjectStoreFactory:
28
+ """Factory class that creates ObjectStore instances."""
29
+
30
+ def __init__(self) -> None:
31
+ self.store_instance: Optional[ObjectStore] = None
32
+
33
+ def store(self) -> ObjectStore:
34
+ """Return an ObjectStore instance and create it, if necessary.
35
+
36
+ Returns
37
+ -------
38
+ ObjectStore
39
+ An ObjectStore instance for storing objects by object_id.
40
+ """
41
+ if self.store_instance is None:
42
+ self.store_instance = InMemoryObjectStore()
43
+ log(DEBUG, "Using InMemoryObjectStore")
44
+ return self.store_instance
@@ -12,11 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Flower SuperNode."""
15
+ """Flower command line interface for SuperNode."""
16
16
 
17
17
 
18
- from .app import run_supernode as run_supernode
18
+ from .flower_supernode import flower_supernode
19
19
 
20
- __all__ = [
21
- "run_supernode",
22
- ]
20
+ __all__ = ["flower_supernode"]
@@ -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
- """Flower SuperNode."""
15
+ """`flower-supernode` command."""
16
16
 
17
17
 
18
18
  import argparse
@@ -43,11 +43,10 @@ from flwr.common.exit import ExitCode, flwr_exit
43
43
  from flwr.common.exit_handlers import register_exit_handlers
44
44
  from flwr.common.logger import log
45
45
 
46
- from ..clientapp.utils import get_load_client_app_fn
47
46
  from ..start_client_internal import start_client_internal
48
47
 
49
48
 
50
- def run_supernode() -> None:
49
+ def flower_supernode() -> None:
51
50
  """Run Flower SuperNode."""
52
51
  args = _parse_args_run_supernode().parse_args()
53
52
 
@@ -64,12 +63,6 @@ def run_supernode() -> None:
64
63
  )
65
64
 
66
65
  root_certificates = try_obtain_root_certificates(args, args.superlink)
67
- load_fn = get_load_client_app_fn(
68
- default_app_ref="",
69
- app_path=None,
70
- flwr_dir=args.flwr_dir,
71
- multi_app=True,
72
- )
73
66
  authentication_keys = _try_setup_client_authentication(args)
74
67
 
75
68
  log(DEBUG, "Isolation mode: %s", args.isolation)
@@ -82,7 +75,6 @@ def run_supernode() -> None:
82
75
 
83
76
  start_client_internal(
84
77
  server_address=args.superlink,
85
- load_client_app_fn=load_fn,
86
78
  transport=args.transport,
87
79
  root_certificates=root_certificates,
88
80
  insecure=args.insecure,