flwr-nightly 1.9.0.dev20240409__py3-none-any.whl → 1.9.0.dev20240414__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.

flwr/cli/new/new.py CHANGED
@@ -22,7 +22,12 @@ from typing import Dict, Optional
22
22
  import typer
23
23
  from typing_extensions import Annotated
24
24
 
25
- from ..utils import prompt_options, prompt_text
25
+ from ..utils import (
26
+ is_valid_project_name,
27
+ prompt_options,
28
+ prompt_text,
29
+ sanitize_project_name,
30
+ )
26
31
 
27
32
 
28
33
  class MlFramework(str, Enum):
@@ -81,6 +86,16 @@ def new(
81
86
  ] = None,
82
87
  ) -> None:
83
88
  """Create new Flower project."""
89
+ if project_name is None:
90
+ project_name = prompt_text("Please provide project name")
91
+ if not is_valid_project_name(project_name):
92
+ project_name = prompt_text(
93
+ "Please provide a name that only contains "
94
+ "characters in {'_', 'a-zA-Z', '0-9'}",
95
+ predicate=is_valid_project_name,
96
+ default=sanitize_project_name(project_name),
97
+ )
98
+
84
99
  print(
85
100
  typer.style(
86
101
  f"🔨 Creating Flower project {project_name}...",
@@ -89,9 +104,6 @@ def new(
89
104
  )
90
105
  )
91
106
 
92
- if project_name is None:
93
- project_name = prompt_text("Please provide project name")
94
-
95
107
  if framework is not None:
96
108
  framework_str = str(framework.value)
97
109
  else:
@@ -116,7 +128,6 @@ def new(
116
128
  # List of files to render
117
129
  files = {
118
130
  "README.md": {"template": "app/README.md.tpl"},
119
- "requirements.txt": {"template": f"app/requirements.{framework_str}.txt.tpl"},
120
131
  "flower.toml": {"template": "app/flower.toml.tpl"},
121
132
  "pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
122
133
  f"{pnl}/__init__.py": {"template": "app/code/__init__.py.tpl"},
@@ -3,11 +3,7 @@
3
3
  ## Install dependencies
4
4
 
5
5
  ```bash
6
- # Using pip
7
6
  pip install .
8
-
9
- # Or using Poetry
10
- poetry install
11
7
  ```
12
8
 
13
9
  ## Run (Simulation Engine)
@@ -1,19 +1,19 @@
1
1
  [build-system]
2
- requires = ["poetry-core>=1.4.0"]
3
- build-backend = "poetry.core.masonry.api"
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
4
 
5
- [tool.poetry]
5
+ [project]
6
6
  name = "$project_name"
7
7
  version = "1.0.0"
8
8
  description = ""
9
- license = "Apache-2.0"
10
9
  authors = [
11
- "The Flower Authors <hello@flower.ai>",
10
+ { name = "The Flower Authors", email = "hello@flower.ai" },
11
+ ]
12
+ license = {text = "Apache License (2.0)"}
13
+ dependencies = [
14
+ "flwr[simulation]>=1.8.0,<2.0",
15
+ "numpy>=1.21.0",
12
16
  ]
13
- readme = "README.md"
14
17
 
15
- [tool.poetry.dependencies]
16
- python = "^3.9"
17
- # Mandatory dependencies
18
- numpy = "^1.21.0"
19
- flwr = { version = "^1.8.0", extras = ["simulation"] }
18
+ [tool.hatch.build.targets.wheel]
19
+ packages = ["."]
@@ -1,21 +1,21 @@
1
1
  [build-system]
2
- requires = ["poetry-core>=1.4.0"]
3
- build-backend = "poetry.core.masonry.api"
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
4
 
5
- [tool.poetry]
5
+ [project]
6
6
  name = "$project_name"
7
7
  version = "1.0.0"
8
8
  description = ""
9
- license = "Apache-2.0"
10
9
  authors = [
11
- "The Flower Authors <hello@flower.ai>",
10
+ { name = "The Flower Authors", email = "hello@flower.ai" },
11
+ ]
12
+ license = {text = "Apache License (2.0)"}
13
+ dependencies = [
14
+ "flwr[simulation]>=1.8.0,<2.0",
15
+ "flwr-datasets[vision]>=0.0.2,<1.0.0",
16
+ "torch==2.2.1",
17
+ "torchvision==0.17.1",
12
18
  ]
13
- readme = "README.md"
14
19
 
15
- [tool.poetry.dependencies]
16
- python = "^3.9"
17
- # Mandatory dependencies
18
- flwr = { version = "^1.8.0", extras = ["simulation"] }
19
- flwr-datasets = { version = "0.0.2", extras = ["vision"] }
20
- torch = "2.2.1"
21
- torchvision = "0.17.1"
20
+ [tool.hatch.build.targets.wheel]
21
+ packages = ["."]
@@ -1,21 +1,20 @@
1
1
  [build-system]
2
- requires = ["poetry-core>=1.4.0"]
3
- build-backend = "poetry.core.masonry.api"
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
4
 
5
- [tool.poetry]
5
+ [project]
6
6
  name = "$project_name"
7
7
  version = "1.0.0"
8
8
  description = ""
9
- license = "Apache-2.0"
10
9
  authors = [
11
- "The Flower Authors <hello@flower.ai>",
10
+ { name = "The Flower Authors", email = "hello@flower.ai" },
11
+ ]
12
+ license = {text = "Apache License (2.0)"}
13
+ dependencies = [
14
+ "flwr[simulation]>=1.8.0,<2.0",
15
+ "flwr-datasets[vision]>=0.0.2,<1.0.0",
16
+ "tensorflow>=2.11.1",
12
17
  ]
13
- readme = "README.md"
14
18
 
15
- [tool.poetry.dependencies]
16
- python = ">=3.9,<3.11"
17
- # Mandatory dependencies
18
- flwr = { version = "^1.8.0", extras = ["simulation"] }
19
- flwr-datasets = { version = "^0.0.2", extras = ["vision"] }
20
- tensorflow-cpu = { version = ">=2.9.1,<2.11.1 || >2.11.1", markers = "platform_machine == \"x86_64\"" }
21
- tensorflow-macos = { version = ">=2.9.1,<2.11.1 || >2.11.1", markers = "sys_platform == \"darwin\" and platform_machine == \"arm64\"" }
19
+ [tool.hatch.build.targets.wheel]
20
+ packages = ["."]
flwr/cli/utils.py CHANGED
@@ -14,18 +14,23 @@
14
14
  # ==============================================================================
15
15
  """Flower command line interface utils."""
16
16
 
17
- from typing import List, cast
17
+ from typing import Callable, List, Optional, cast
18
18
 
19
19
  import typer
20
20
 
21
21
 
22
- def prompt_text(text: str) -> str:
22
+ def prompt_text(
23
+ text: str,
24
+ predicate: Callable[[str], bool] = lambda _: True,
25
+ default: Optional[str] = None,
26
+ ) -> str:
23
27
  """Ask user to enter text input."""
24
28
  while True:
25
29
  result = typer.prompt(
26
- typer.style(f"\n💬 {text}", fg=typer.colors.MAGENTA, bold=True)
30
+ typer.style(f"\n💬 {text}", fg=typer.colors.MAGENTA, bold=True),
31
+ default=default,
27
32
  )
28
- if len(result) > 0:
33
+ if predicate(result) and len(result) > 0:
29
34
  break
30
35
  print(typer.style("❌ Invalid entry", fg=typer.colors.RED, bold=True))
31
36
 
@@ -65,3 +70,54 @@ def prompt_options(text: str, options: List[str]) -> str:
65
70
 
66
71
  result = options[int(index)]
67
72
  return result
73
+
74
+
75
+ def is_valid_project_name(name: str) -> bool:
76
+ """Check if the given string is a valid Python module name.
77
+
78
+ A valid module name must start with a letter or an underscore, and can only contain
79
+ letters, digits, and underscores.
80
+ """
81
+ if not name:
82
+ return False
83
+
84
+ # Check if the first character is a letter or underscore
85
+ if not (name[0].isalpha() or name[0] == "_"):
86
+ return False
87
+
88
+ # Check if the rest of the characters are valid (letter, digit, or underscore)
89
+ for char in name[1:]:
90
+ if not (char.isalnum() or char == "_"):
91
+ return False
92
+
93
+ return True
94
+
95
+
96
+ def sanitize_project_name(name: str) -> str:
97
+ """Sanitize the given string to make it a valid Python module name.
98
+
99
+ This version replaces hyphens with underscores, removes any characters not allowed
100
+ in Python module names, makes the string lowercase, and ensures it starts with a
101
+ valid character.
102
+ """
103
+ # Replace '-' with '_'
104
+ name_with_underscores = name.replace("-", "_").replace(" ", "_")
105
+
106
+ # Allowed characters in a module name: letters, digits, underscore
107
+ allowed_chars = set(
108
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
109
+ )
110
+
111
+ # Make the string lowercase
112
+ sanitized_name = name_with_underscores.lower()
113
+
114
+ # Remove any characters not allowed in Python module names
115
+ sanitized_name = "".join(c for c in sanitized_name if c in allowed_chars)
116
+
117
+ # Ensure the first character is a letter or underscore
118
+ if sanitized_name and (
119
+ sanitized_name[0].isdigit() or sanitized_name[0] not in allowed_chars
120
+ ):
121
+ sanitized_name = "_" + sanitized_name
122
+
123
+ return sanitized_name
flwr/client/heartbeat.py CHANGED
@@ -66,7 +66,9 @@ def start_ping_loop(
66
66
  asynchronous ping operations. The loop can be terminated through the provided stop
67
67
  event.
68
68
  """
69
- thread = threading.Thread(target=_ping_loop, args=(ping_fn, stop_event))
69
+ thread = threading.Thread(
70
+ target=_ping_loop, args=(ping_fn, stop_event), daemon=True
71
+ )
70
72
  thread.start()
71
73
 
72
74
  return thread
flwr/proto/driver_pb2.py CHANGED
@@ -16,7 +16,7 @@ from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
16
16
  from flwr.proto import task_pb2 as flwr_dot_proto_dot_task__pb2
17
17
 
18
18
 
19
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x66lwr/proto/driver.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\"\x12\n\x10\x43reateRunRequest\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"!\n\x0fGetNodesRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"3\n\x10GetNodesResponse\x12\x1f\n\x05nodes\x18\x01 \x03(\x0b\x32\x10.flwr.proto.Node\"@\n\x12PushTaskInsRequest\x12*\n\rtask_ins_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"\'\n\x13PushTaskInsResponse\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"F\n\x12PullTaskResRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"A\n\x13PullTaskResResponse\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes2\xc1\x02\n\x06\x44river\x12J\n\tCreateRun\x12\x1c.flwr.proto.CreateRunRequest\x1a\x1d.flwr.proto.CreateRunResponse\"\x00\x12G\n\x08GetNodes\x12\x1b.flwr.proto.GetNodesRequest\x1a\x1c.flwr.proto.GetNodesResponse\"\x00\x12P\n\x0bPushTaskIns\x12\x1e.flwr.proto.PushTaskInsRequest\x1a\x1f.flwr.proto.PushTaskInsResponse\"\x00\x12P\n\x0bPullTaskRes\x12\x1e.flwr.proto.PullTaskResRequest\x1a\x1f.flwr.proto.PullTaskResResponse\"\x00\x62\x06proto3')
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x66lwr/proto/driver.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\"7\n\x10\x43reateRunRequest\x12\x0e\n\x06\x66\x61\x62_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x02 \x01(\t\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"!\n\x0fGetNodesRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"3\n\x10GetNodesResponse\x12\x1f\n\x05nodes\x18\x01 \x03(\x0b\x32\x10.flwr.proto.Node\"@\n\x12PushTaskInsRequest\x12*\n\rtask_ins_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"\'\n\x13PushTaskInsResponse\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"F\n\x12PullTaskResRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"A\n\x13PullTaskResResponse\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes2\xc1\x02\n\x06\x44river\x12J\n\tCreateRun\x12\x1c.flwr.proto.CreateRunRequest\x1a\x1d.flwr.proto.CreateRunResponse\"\x00\x12G\n\x08GetNodes\x12\x1b.flwr.proto.GetNodesRequest\x1a\x1c.flwr.proto.GetNodesResponse\"\x00\x12P\n\x0bPushTaskIns\x12\x1e.flwr.proto.PushTaskInsRequest\x1a\x1f.flwr.proto.PushTaskInsResponse\"\x00\x12P\n\x0bPullTaskRes\x12\x1e.flwr.proto.PullTaskResRequest\x1a\x1f.flwr.proto.PullTaskResResponse\"\x00\x62\x06proto3')
20
20
 
21
21
  _globals = globals()
22
22
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -24,21 +24,21 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.driver_pb2', _gl
24
24
  if _descriptor._USE_C_DESCRIPTORS == False:
25
25
  DESCRIPTOR._options = None
26
26
  _globals['_CREATERUNREQUEST']._serialized_start=85
27
- _globals['_CREATERUNREQUEST']._serialized_end=103
28
- _globals['_CREATERUNRESPONSE']._serialized_start=105
29
- _globals['_CREATERUNRESPONSE']._serialized_end=140
30
- _globals['_GETNODESREQUEST']._serialized_start=142
31
- _globals['_GETNODESREQUEST']._serialized_end=175
32
- _globals['_GETNODESRESPONSE']._serialized_start=177
33
- _globals['_GETNODESRESPONSE']._serialized_end=228
34
- _globals['_PUSHTASKINSREQUEST']._serialized_start=230
35
- _globals['_PUSHTASKINSREQUEST']._serialized_end=294
36
- _globals['_PUSHTASKINSRESPONSE']._serialized_start=296
37
- _globals['_PUSHTASKINSRESPONSE']._serialized_end=335
38
- _globals['_PULLTASKRESREQUEST']._serialized_start=337
39
- _globals['_PULLTASKRESREQUEST']._serialized_end=407
40
- _globals['_PULLTASKRESRESPONSE']._serialized_start=409
41
- _globals['_PULLTASKRESRESPONSE']._serialized_end=474
42
- _globals['_DRIVER']._serialized_start=477
43
- _globals['_DRIVER']._serialized_end=798
27
+ _globals['_CREATERUNREQUEST']._serialized_end=140
28
+ _globals['_CREATERUNRESPONSE']._serialized_start=142
29
+ _globals['_CREATERUNRESPONSE']._serialized_end=177
30
+ _globals['_GETNODESREQUEST']._serialized_start=179
31
+ _globals['_GETNODESREQUEST']._serialized_end=212
32
+ _globals['_GETNODESRESPONSE']._serialized_start=214
33
+ _globals['_GETNODESRESPONSE']._serialized_end=265
34
+ _globals['_PUSHTASKINSREQUEST']._serialized_start=267
35
+ _globals['_PUSHTASKINSREQUEST']._serialized_end=331
36
+ _globals['_PUSHTASKINSRESPONSE']._serialized_start=333
37
+ _globals['_PUSHTASKINSRESPONSE']._serialized_end=372
38
+ _globals['_PULLTASKRESREQUEST']._serialized_start=374
39
+ _globals['_PULLTASKRESREQUEST']._serialized_end=444
40
+ _globals['_PULLTASKRESRESPONSE']._serialized_start=446
41
+ _globals['_PULLTASKRESRESPONSE']._serialized_end=511
42
+ _globals['_DRIVER']._serialized_start=514
43
+ _globals['_DRIVER']._serialized_end=835
44
44
  # @@protoc_insertion_point(module_scope)
flwr/proto/driver_pb2.pyi CHANGED
@@ -16,8 +16,16 @@ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
16
16
  class CreateRunRequest(google.protobuf.message.Message):
17
17
  """CreateRun"""
18
18
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
19
+ FAB_ID_FIELD_NUMBER: builtins.int
20
+ FAB_VERSION_FIELD_NUMBER: builtins.int
21
+ fab_id: typing.Text
22
+ fab_version: typing.Text
19
23
  def __init__(self,
24
+ *,
25
+ fab_id: typing.Text = ...,
26
+ fab_version: typing.Text = ...,
20
27
  ) -> None: ...
28
+ def ClearField(self, field_name: typing_extensions.Literal["fab_id",b"fab_id","fab_version",b"fab_version"]) -> None: ...
21
29
  global___CreateRunRequest = CreateRunRequest
22
30
 
23
31
  class CreateRunResponse(google.protobuf.message.Message):
flwr/proto/fleet_pb2.py CHANGED
@@ -16,7 +16,7 @@ from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
16
16
  from flwr.proto import task_pb2 as flwr_dot_proto_dot_task__pb2
17
17
 
18
18
 
19
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\"*\n\x11\x43reateNodeRequest\x12\x15\n\rping_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"D\n\x0bPingRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x15\n\rping_interval\x18\x02 \x01(\x01\"\x1f\n\x0cPingResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"F\n\x12PullTaskInsRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"k\n\x13PullTaskInsResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rtask_ins_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"@\n\x12PushTaskResRequest\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes\"\xae\x01\n\x13PushTaskResResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12=\n\x07results\x18\x02 \x03(\x0b\x32,.flwr.proto.PushTaskResResponse.ResultsEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\x86\x03\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12;\n\x04Ping\x12\x17.flwr.proto.PingRequest\x1a\x18.flwr.proto.PingResponse\"\x00\x12P\n\x0bPullTaskIns\x12\x1e.flwr.proto.PullTaskInsRequest\x1a\x1f.flwr.proto.PullTaskInsResponse\"\x00\x12P\n\x0bPushTaskRes\x12\x1e.flwr.proto.PushTaskResRequest\x1a\x1f.flwr.proto.PushTaskResResponse\"\x00\x62\x06proto3')
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\"*\n\x11\x43reateNodeRequest\x12\x15\n\rping_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"D\n\x0bPingRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x15\n\rping_interval\x18\x02 \x01(\x01\"\x1f\n\x0cPingResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"F\n\x12PullTaskInsRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"k\n\x13PullTaskInsResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rtask_ins_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"@\n\x12PushTaskResRequest\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes\"\xae\x01\n\x13PushTaskResResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12=\n\x07results\x18\x02 \x03(\x0b\x32,.flwr.proto.PushTaskResResponse.ResultsEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\":\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\"\x1f\n\rGetRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Run\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\xc9\x03\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12;\n\x04Ping\x12\x17.flwr.proto.PingRequest\x1a\x18.flwr.proto.PingResponse\"\x00\x12P\n\x0bPullTaskIns\x12\x1e.flwr.proto.PullTaskInsRequest\x1a\x1f.flwr.proto.PullTaskInsResponse\"\x00\x12P\n\x0bPushTaskRes\x12\x1e.flwr.proto.PushTaskResRequest\x1a\x1f.flwr.proto.PushTaskResResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x62\x06proto3')
20
20
 
21
21
  _globals = globals()
22
22
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -47,8 +47,14 @@ if _descriptor._USE_C_DESCRIPTORS == False:
47
47
  _globals['_PUSHTASKRESRESPONSE']._serialized_end=782
48
48
  _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_start=736
49
49
  _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_end=782
50
- _globals['_RECONNECT']._serialized_start=784
51
- _globals['_RECONNECT']._serialized_end=814
52
- _globals['_FLEET']._serialized_start=817
53
- _globals['_FLEET']._serialized_end=1207
50
+ _globals['_RUN']._serialized_start=784
51
+ _globals['_RUN']._serialized_end=842
52
+ _globals['_GETRUNREQUEST']._serialized_start=844
53
+ _globals['_GETRUNREQUEST']._serialized_end=875
54
+ _globals['_GETRUNRESPONSE']._serialized_start=877
55
+ _globals['_GETRUNRESPONSE']._serialized_end=923
56
+ _globals['_RECONNECT']._serialized_start=925
57
+ _globals['_RECONNECT']._serialized_end=955
58
+ _globals['_FLEET']._serialized_start=958
59
+ _globals['_FLEET']._serialized_end=1415
54
60
  # @@protoc_insertion_point(module_scope)
flwr/proto/fleet_pb2.pyi CHANGED
@@ -164,6 +164,48 @@ class PushTaskResResponse(google.protobuf.message.Message):
164
164
  def ClearField(self, field_name: typing_extensions.Literal["reconnect",b"reconnect","results",b"results"]) -> None: ...
165
165
  global___PushTaskResResponse = PushTaskResResponse
166
166
 
167
+ class Run(google.protobuf.message.Message):
168
+ """GetRun messages"""
169
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
170
+ RUN_ID_FIELD_NUMBER: builtins.int
171
+ FAB_ID_FIELD_NUMBER: builtins.int
172
+ FAB_VERSION_FIELD_NUMBER: builtins.int
173
+ run_id: builtins.int
174
+ fab_id: typing.Text
175
+ fab_version: typing.Text
176
+ def __init__(self,
177
+ *,
178
+ run_id: builtins.int = ...,
179
+ fab_id: typing.Text = ...,
180
+ fab_version: typing.Text = ...,
181
+ ) -> None: ...
182
+ def ClearField(self, field_name: typing_extensions.Literal["fab_id",b"fab_id","fab_version",b"fab_version","run_id",b"run_id"]) -> None: ...
183
+ global___Run = Run
184
+
185
+ class GetRunRequest(google.protobuf.message.Message):
186
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
187
+ RUN_ID_FIELD_NUMBER: builtins.int
188
+ run_id: builtins.int
189
+ def __init__(self,
190
+ *,
191
+ run_id: builtins.int = ...,
192
+ ) -> None: ...
193
+ def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ...
194
+ global___GetRunRequest = GetRunRequest
195
+
196
+ class GetRunResponse(google.protobuf.message.Message):
197
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
198
+ RUN_FIELD_NUMBER: builtins.int
199
+ @property
200
+ def run(self) -> global___Run: ...
201
+ def __init__(self,
202
+ *,
203
+ run: typing.Optional[global___Run] = ...,
204
+ ) -> None: ...
205
+ def HasField(self, field_name: typing_extensions.Literal["run",b"run"]) -> builtins.bool: ...
206
+ def ClearField(self, field_name: typing_extensions.Literal["run",b"run"]) -> None: ...
207
+ global___GetRunResponse = GetRunResponse
208
+
167
209
  class Reconnect(google.protobuf.message.Message):
168
210
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
169
211
  RECONNECT_FIELD_NUMBER: builtins.int
@@ -39,6 +39,11 @@ class FleetStub(object):
39
39
  request_serializer=flwr_dot_proto_dot_fleet__pb2.PushTaskResRequest.SerializeToString,
40
40
  response_deserializer=flwr_dot_proto_dot_fleet__pb2.PushTaskResResponse.FromString,
41
41
  )
42
+ self.GetRun = channel.unary_unary(
43
+ '/flwr.proto.Fleet/GetRun',
44
+ request_serializer=flwr_dot_proto_dot_fleet__pb2.GetRunRequest.SerializeToString,
45
+ response_deserializer=flwr_dot_proto_dot_fleet__pb2.GetRunResponse.FromString,
46
+ )
42
47
 
43
48
 
44
49
  class FleetServicer(object):
@@ -80,6 +85,12 @@ class FleetServicer(object):
80
85
  context.set_details('Method not implemented!')
81
86
  raise NotImplementedError('Method not implemented!')
82
87
 
88
+ def GetRun(self, request, context):
89
+ """Missing associated documentation comment in .proto file."""
90
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
91
+ context.set_details('Method not implemented!')
92
+ raise NotImplementedError('Method not implemented!')
93
+
83
94
 
84
95
  def add_FleetServicer_to_server(servicer, server):
85
96
  rpc_method_handlers = {
@@ -108,6 +119,11 @@ def add_FleetServicer_to_server(servicer, server):
108
119
  request_deserializer=flwr_dot_proto_dot_fleet__pb2.PushTaskResRequest.FromString,
109
120
  response_serializer=flwr_dot_proto_dot_fleet__pb2.PushTaskResResponse.SerializeToString,
110
121
  ),
122
+ 'GetRun': grpc.unary_unary_rpc_method_handler(
123
+ servicer.GetRun,
124
+ request_deserializer=flwr_dot_proto_dot_fleet__pb2.GetRunRequest.FromString,
125
+ response_serializer=flwr_dot_proto_dot_fleet__pb2.GetRunResponse.SerializeToString,
126
+ ),
111
127
  }
112
128
  generic_handler = grpc.method_handlers_generic_handler(
113
129
  'flwr.proto.Fleet', rpc_method_handlers)
@@ -202,3 +218,20 @@ class Fleet(object):
202
218
  flwr_dot_proto_dot_fleet__pb2.PushTaskResResponse.FromString,
203
219
  options, channel_credentials,
204
220
  insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
221
+
222
+ @staticmethod
223
+ def GetRun(request,
224
+ target,
225
+ options=(),
226
+ channel_credentials=None,
227
+ call_credentials=None,
228
+ insecure=False,
229
+ compression=None,
230
+ wait_for_ready=None,
231
+ timeout=None,
232
+ metadata=None):
233
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.Fleet/GetRun',
234
+ flwr_dot_proto_dot_fleet__pb2.GetRunRequest.SerializeToString,
235
+ flwr_dot_proto_dot_fleet__pb2.GetRunResponse.FromString,
236
+ options, channel_credentials,
237
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -36,6 +36,10 @@ class FleetStub:
36
36
  HTTP API path: /api/v1/fleet/push-task-res
37
37
  """
38
38
 
39
+ GetRun: grpc.UnaryUnaryMultiCallable[
40
+ flwr.proto.fleet_pb2.GetRunRequest,
41
+ flwr.proto.fleet_pb2.GetRunResponse]
42
+
39
43
 
40
44
  class FleetServicer(metaclass=abc.ABCMeta):
41
45
  @abc.abstractmethod
@@ -78,5 +82,11 @@ class FleetServicer(metaclass=abc.ABCMeta):
78
82
  """
79
83
  pass
80
84
 
85
+ @abc.abstractmethod
86
+ def GetRun(self,
87
+ request: flwr.proto.fleet_pb2.GetRunRequest,
88
+ context: grpc.ServicerContext,
89
+ ) -> flwr.proto.fleet_pb2.GetRunResponse: ...
90
+
81
91
 
82
92
  def add_FleetServicer_to_server(servicer: FleetServicer, server: grpc.Server) -> None: ...
@@ -16,7 +16,6 @@
16
16
 
17
17
 
18
18
  import threading
19
- import time
20
19
  from typing import Dict, Tuple
21
20
 
22
21
  from ..client_manager import ClientManager
@@ -60,6 +59,7 @@ def start_update_client_manager_thread(
60
59
  client_manager,
61
60
  f_stop,
62
61
  ),
62
+ daemon=True,
63
63
  )
64
64
  thread.start()
65
65
 
@@ -99,4 +99,5 @@ def _update_client_manager(
99
99
  raise RuntimeError("Could not register node.")
100
100
 
101
101
  # Sleep for 3 seconds
102
- time.sleep(3)
102
+ if not f_stop.is_set():
103
+ f_stop.wait(3)
@@ -26,6 +26,8 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
26
26
  CreateNodeResponse,
27
27
  DeleteNodeRequest,
28
28
  DeleteNodeResponse,
29
+ GetRunRequest,
30
+ GetRunResponse,
29
31
  PingRequest,
30
32
  PingResponse,
31
33
  PullTaskInsRequest,
@@ -90,3 +92,13 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
90
92
  request=request,
91
93
  state=self.state_factory.state(),
92
94
  )
95
+
96
+ def GetRun(
97
+ self, request: GetRunRequest, context: grpc.ServicerContext
98
+ ) -> GetRunResponse:
99
+ """Get run information."""
100
+ log(INFO, "FleetServicer.GetRun")
101
+ return message_handler.get_run(
102
+ request=request,
103
+ state=self.state_factory.state(),
104
+ )
@@ -24,6 +24,8 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
24
24
  CreateNodeResponse,
25
25
  DeleteNodeRequest,
26
26
  DeleteNodeResponse,
27
+ GetRunRequest,
28
+ GetRunResponse,
27
29
  PingRequest,
28
30
  PingResponse,
29
31
  PullTaskInsRequest,
@@ -101,3 +103,10 @@ def push_task_res(request: PushTaskResRequest, state: State) -> PushTaskResRespo
101
103
  results={str(task_id): 0},
102
104
  )
103
105
  return response
106
+
107
+
108
+ def get_run(
109
+ request: GetRunRequest, state: State # pylint: disable=W0613
110
+ ) -> GetRunResponse:
111
+ """Get run information."""
112
+ return GetRunResponse()
@@ -21,6 +21,7 @@ from flwr.common.constant import MISSING_EXTRA_REST
21
21
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
22
22
  CreateNodeRequest,
23
23
  DeleteNodeRequest,
24
+ GetRunRequest,
24
25
  PingRequest,
25
26
  PullTaskInsRequest,
26
27
  PushTaskResRequest,
@@ -179,12 +180,41 @@ async def ping(request: Request) -> Response:
179
180
  )
180
181
 
181
182
 
183
+ async def get_run(request: Request) -> Response:
184
+ """GetRun."""
185
+ _check_headers(request.headers)
186
+
187
+ # Get the request body as raw bytes
188
+ get_run_request_bytes: bytes = await request.body()
189
+
190
+ # Deserialize ProtoBuf
191
+ get_run_request_proto = GetRunRequest()
192
+ get_run_request_proto.ParseFromString(get_run_request_bytes)
193
+
194
+ # Get state from app
195
+ state: State = app.state.STATE_FACTORY.state()
196
+
197
+ # Handle message
198
+ get_run_response_proto = message_handler.get_run(
199
+ request=get_run_request_proto, state=state
200
+ )
201
+
202
+ # Return serialized ProtoBuf
203
+ get_run_response_bytes = get_run_response_proto.SerializeToString()
204
+ return Response(
205
+ status_code=200,
206
+ content=get_run_response_bytes,
207
+ headers={"Content-Type": "application/protobuf"},
208
+ )
209
+
210
+
182
211
  routes = [
183
212
  Route("/api/v0/fleet/create-node", create_node, methods=["POST"]),
184
213
  Route("/api/v0/fleet/delete-node", delete_node, methods=["POST"]),
185
214
  Route("/api/v0/fleet/pull-task-ins", pull_task_ins, methods=["POST"]),
186
215
  Route("/api/v0/fleet/push-task-res", push_task_res, methods=["POST"]),
187
216
  Route("/api/v0/fleet/ping", ping, methods=["POST"]),
217
+ Route("/api/v0/fleet/get-run", get_run, methods=["POST"]),
188
218
  ]
189
219
 
190
220
  app: Starlette = Starlette(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.9.0.dev20240409
3
+ Version: 1.9.0.dev20240414
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -4,9 +4,9 @@ flwr/cli/app.py,sha256=38thPnMydBmNAxNE9mz4By-KdRUhJfoUgeDuAxMYF_U,1095
4
4
  flwr/cli/example.py,sha256=1bGDYll3BXQY2kRqSN-oICqS5n1b9m0g0RvXTopXHl4,2215
5
5
  flwr/cli/flower_toml.py,sha256=gypY4zOe6Mx_Xzz5vsSzGRppWBaCnipiksBTrox_r3k,4675
6
6
  flwr/cli/new/__init__.py,sha256=cQzK1WH4JP2awef1t2UQ2xjl1agVEz9rwutV18SWV1k,789
7
- flwr/cli/new/new.py,sha256=FqQoFATat1O9UGEUdWrAFCOUOEtnIRn3USr-Lv8osi0,5016
7
+ flwr/cli/new/new.py,sha256=gxl4j0b9Ojsh5vcjmwPxEY4wrxDQg8JaLs7-Q61xvFM,5300
8
8
  flwr/cli/new/templates/__init__.py,sha256=4luU8RL-CK8JJCstQ_ON809W9bNTkY1l9zSaPKBkgwY,725
9
- flwr/cli/new/templates/app/README.md.tpl,sha256=AvM6QCfQd1acUV3fkXOwgypZ5_52L3kKu53owXsjgcc,714
9
+ flwr/cli/new/templates/app/README.md.tpl,sha256=_qGtgpKYKoCJVjQnvlBMKvFs_1gzTcL908I3KJg0oAM,668
10
10
  flwr/cli/new/templates/app/__init__.py,sha256=DU7QMY7IhMQyuwm_tja66xU0KXTWQFqzfTqwg-_NJdE,729
11
11
  flwr/cli/new/templates/app/code/__init__.py,sha256=EM6vfvgAILKPaPn7H1wMV1Wi01WyZCP_Eg6NxD6oWg8,736
12
12
  flwr/cli/new/templates/app/code/__init__.py.tpl,sha256=olwrBeJemHNBWvjc6gJURloFRqW40dAy7FRQA5pDqHU,21
@@ -18,15 +18,12 @@ flwr/cli/new/templates/app/code/server.pytorch.py.tpl,sha256=xtKvUivNMzgOcLSOtnj
18
18
  flwr/cli/new/templates/app/code/server.tensorflow.py.tpl,sha256=d6J5VM681d0j4hj1Duaj1WQyeFoyCiEZh4o4J8zH-_M,48
19
19
  flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=NvajdZN-eTyfdqKK0v2MrvWITXw9BjJ3Ri5c1haPJDs,3684
20
20
  flwr/cli/new/templates/app/flower.toml.tpl,sha256=gJ5MZ7zaiaVvIEt5X_kkU-SU2NmeXkAZ9NXJS00-Axw,269
21
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=5kGEAPrHKHFfzxmKy1AvrHMcp46nZwnQb2z5zPX8XZY,408
22
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=SUmoMyRodzYkxElKDF_rgP-Ftirw4hKUoOE8EcRpQb0,488
23
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=6odFG__2Wb8CHNUDJRjA0H3bOkZ8Z7iziTNJKX2_SOI,697
24
- flwr/cli/new/templates/app/requirements.numpy.txt.tpl,sha256=YfJLjL-ONv0hnw5k4EfHv6uMpaqfLzOhkT_P4aWv5Fo,30
25
- flwr/cli/new/templates/app/requirements.pytorch.txt.tpl,sha256=3dvhiFgiOw3HAHCDmyiqvBSTF492wQm75KUKzVCOkUc,86
26
- flwr/cli/new/templates/app/requirements.tensorflow.txt.tpl,sha256=MsiO0GbUe35h5giVMaE2YykKMAhtC5ccAc_4EcmJUNs,209
21
+ flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=00Qp7cQhOvW0Bx7j82mIP9BXT6D0ysbzqZHDEPoZQyU,390
22
+ flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=A2AqU5lh2VBHOCX_S7rTMYZc5JmPqwEVIg9KsIjLgh8,459
23
+ flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=vLmeOFCIvMVUoIDgGtLinAUQy6jKjqmgHKcuEqhVYkw,438
27
24
  flwr/cli/run/__init__.py,sha256=oCd6HmQDx-sqver1gecgx-uMA38BLTSiiKpl7RGNceg,789
28
25
  flwr/cli/run/run.py,sha256=C7Yh-Y0f64PEabb9733jBKIhhOUFpcRmCZJIDtv-NG8,2329
29
- flwr/cli/utils.py,sha256=_V2BlFVNNG2naZrq227fZ8o4TxBN_hB-4fQsen9uQoo,2300
26
+ flwr/cli/utils.py,sha256=33m5ELefA43VhJwtBHW5ntWkP7X5Tk_5A2s1OcaSBYg,4153
30
27
  flwr/client/__init__.py,sha256=futk_IdY_N1h8BTve4Iru51bxm7H1gv58ZPIXWi5XUA,1187
31
28
  flwr/client/app.py,sha256=B48cQa-kb_0WzdtufTXuaoEyrynGWMQCqxdUz_sAKek,26193
32
29
  flwr/client/client.py,sha256=Vp9UkOkoHdNfn6iMYZsj_5m_GICiFfUlKEVaLad-YhM,8183
@@ -36,7 +33,7 @@ flwr/client/grpc_client/__init__.py,sha256=LsnbqXiJhgQcB0XzAlUQgPx011Uf7Y7yabIC1
36
33
  flwr/client/grpc_client/connection.py,sha256=w3Lble9-eCzNOR7fBUsVedVCK4ui9QPhK7i7Ew_a5Vk,8717
37
34
  flwr/client/grpc_rere_client/__init__.py,sha256=avn6W_vHEM_yZEB1S7hCZgnTbXb6ZujqRP_vAzyXu-0,752
38
35
  flwr/client/grpc_rere_client/connection.py,sha256=JaQIQYUJnmZHfqrGBxYZmEtyC-rUdCCaK1HrMcOXEig,8560
39
- flwr/client/heartbeat.py,sha256=6Ix2Du9SDlXU_nre48WIDUXDy3AVoZsGKacSq2NqT5c,2377
36
+ flwr/client/heartbeat.py,sha256=cx37mJBH8LyoIN4Lks85wtqT1mnU5GulQnr4pGCvAq0,2404
40
37
  flwr/client/message_handler/__init__.py,sha256=abHvBRJJiiaAMNgeILQbMOa6h8WqMK2BcnvxwQZFpic,719
41
38
  flwr/client/message_handler/message_handler.py,sha256=ml_FlduAJ5pxO31n1tKRrWfQRSxkMgKLbwXXcRsNSos,6553
42
39
  flwr/client/message_handler/task_handler.py,sha256=ZDJBKmrn2grRMNl1rU1iGs7FiMHL5VmZiSp_6h9GHVU,1824
@@ -91,18 +88,18 @@ flwr/common/telemetry.py,sha256=JkFB6WBOskqAJfzSM-l6tQfRiSi2oiysClfg0-5T7NY,7782
91
88
  flwr/common/typing.py,sha256=3Wu6Ol1Ja6Gb0WdlcXVEn1EHYJbc4oRRJA81vEegxBo,4382
92
89
  flwr/common/version.py,sha256=_RDSMGZPEuGKYViZuXPotDtXMvh4iyDH9XOCO4qtPO8,666
93
90
  flwr/proto/__init__.py,sha256=hbY7JYakwZwCkYgCNlmHdc8rtvfoJbAZLalMdc--CGc,683
94
- flwr/proto/driver_pb2.py,sha256=JHIdjNPTgp6YHD-_lz5ZZFB0VIOR3_GmcaOTN4jndc4,3115
95
- flwr/proto/driver_pb2.pyi,sha256=xwl2AqIWn0SwAlg-x5RUQeqr6DC48eywnqmD7gbaaFs,4670
91
+ flwr/proto/driver_pb2.py,sha256=N5tU8YFOrWBPpNVWRfU6IpnpgNIQjVUQpO8rhFfryYE,3207
92
+ flwr/proto/driver_pb2.pyi,sha256=uTcjWrMsNojfSYrXaXyYmXaB4E8PL5drYs2MuMgN5R8,5016
96
93
  flwr/proto/driver_pb2_grpc.py,sha256=qQBRdQUz4k2K4DVO7kSfWHx-62UJ85HaYKnKCr6JcU8,7304
97
94
  flwr/proto/driver_pb2_grpc.pyi,sha256=NpOM5eCrIPcuWdYrZAayQSDvvFp6cDCVflabhmuvMfo,2022
98
95
  flwr/proto/error_pb2.py,sha256=LarjKL90LbwkXKlhzNrDssgl4DXcvIPve8NVCXHpsKA,1084
99
96
  flwr/proto/error_pb2.pyi,sha256=ZNH4HhJTU_KfMXlyCeg8FwU-fcUYxTqEmoJPtWtHikc,734
100
97
  flwr/proto/error_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
101
98
  flwr/proto/error_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
102
- flwr/proto/fleet_pb2.py,sha256=0PSDvjWer5VDh10L7BckF8-WeNYZzXC2BQQF_E0EacQ,4356
103
- flwr/proto/fleet_pb2.pyi,sha256=45kQ9YINv3VG0nxWSjCN4SppdepjKW8rRBlxKxz7ud4,7571
104
- flwr/proto/fleet_pb2_grpc.py,sha256=U2UeEqWQ7VE58C1ngm_yVniiwBuXfnHmzITYPt6BEtA,9042
105
- flwr/proto/fleet_pb2_grpc.pyi,sha256=Cd8oZqhK9ORMB7iKyW0NBvCeP8Bg1OZbnn_8GzDxEHU,2491
99
+ flwr/proto/fleet_pb2.py,sha256=mKxwomayARq2nQanY3CtnA8ZWqW8NChWsoWeAyGJAOE,5018
100
+ flwr/proto/fleet_pb2.pyi,sha256=yibeuFHsm0ygnJmuyI2V9XNvEt9CLT3dTNUOvAItezU,9161
101
+ flwr/proto/fleet_pb2_grpc.py,sha256=TNt0ydDAXoe1YF2Pl6aNxlGueeOjn0dQ7fdgGx9wd7U,10605
102
+ flwr/proto/fleet_pb2_grpc.pyi,sha256=6flR6x4gB0CZc4YK_MTGeA4zV8Tk_mCcXuxosfDsxGM,2811
106
103
  flwr/proto/node_pb2.py,sha256=1zfXEvgGObglIcaVb4SLFmOcHZvA8eHzEtMFM5A6FYY,1081
107
104
  flwr/proto/node_pb2.pyi,sha256=aX3BHhgXvJE1rvcRnEE_gB-5GcaFQ0SJ88yTE223bjI,751
108
105
  flwr/proto/node_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
@@ -126,7 +123,7 @@ flwr/server/client_manager.py,sha256=T8UDSRJBVD3fyIDI7NTAA-NA7GPrMNNgH2OAF54RRxE
126
123
  flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
127
124
  flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
128
125
  flwr/server/compat/app.py,sha256=3Skh76Rg80B4oME1dJOhZvn9eTfVmTNIQ0jCiZ6CzeQ,5271
129
- flwr/server/compat/app_utils.py,sha256=-Ey5fyRpovmp4nHglVbliITcbxzxX_0qdtZwwfMS4ZI,3450
126
+ flwr/server/compat/app_utils.py,sha256=GGmGApka7J9wHY2tiU_ZDejNvtfW_CZ9NZtb8L30M90,3496
130
127
  flwr/server/compat/driver_client_proxy.py,sha256=QWLl5YJwI6NVADwjQGQJqkLtCfPNT-aRH0NF9yeGEnA,7344
131
128
  flwr/server/compat/legacy_context.py,sha256=D2s7PvQoDnTexuRmf1uG9Von7GUj4Qqyr7qLklSlKAM,1766
132
129
  flwr/server/criterion.py,sha256=ypbAexbztzGUxNen9RCHF91QeqiEQix4t4Ih3E-42MM,1061
@@ -173,11 +170,11 @@ flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py,sha256=LSOmabFXAQxKycQOlipl
173
170
  flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py,sha256=kuD7R1yB1Ite0sNfvjsrnZu83LWGk8fP-yihE1mjQm0,4887
174
171
  flwr/server/superlink/fleet/grpc_bidi/grpc_server.py,sha256=1QyBX5qcFPjMVlv7TrvnQkcET4muvg94Fy9hAQUBYnY,11818
175
172
  flwr/server/superlink/fleet/grpc_rere/__init__.py,sha256=bEJOMWbSlqkw-y5ZHtEXczhoSlAxErcRYffmTMQAV8M,758
176
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=LC_ntiLZMIZkspwjtQ9_MZ4agzArebO4HIVJ3YOrFx8,3036
173
+ flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=YGn1IPpuX-6NDgaG1UbyREbI9iAyKDimZuNeWxbG6s0,3387
177
174
  flwr/server/superlink/fleet/message_handler/__init__.py,sha256=hEY0l61ojH8Iz30_K1btm1HJ6J49iZJSFUsVYqUTw3A,731
178
- flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=rVisujx0B0WZROlp4uwk1KjzgPR7Pit4rBnurF5xXUw,3273
175
+ flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=NfhM-xgIhKqcD2pOkZqwv-zbAB999uVYCjYPtWzo9u4,3473
179
176
  flwr/server/superlink/fleet/rest_rere/__init__.py,sha256=VKDvDq5H8koOUztpmQacVzGJXPLEEkL1Vmolxt3mvnY,735
180
- flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=_tGtARm4x957Fu1EWoDieqOzV9CQZTM4GgKe2GxIOvw,6734
177
+ flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=8gNziOjBA8ygTzfVPYiNkg_qxr-T822Q_Lbo9g2tVyk,7621
181
178
  flwr/server/superlink/fleet/vce/__init__.py,sha256=36MHKiefnJeyjwMQzVUK4m06Ojon3WDcwZGQsAcyVhQ,783
182
179
  flwr/server/superlink/fleet/vce/backend/__init__.py,sha256=oBIzmnrSSRvH_H0vRGEGWhWzQQwqe3zn6e13RsNwlIY,1466
183
180
  flwr/server/superlink/fleet/vce/backend/backend.py,sha256=LJsKl7oixVvptcG98Rd9ejJycNWcEVB0ODvSreLGp-A,2260
@@ -206,8 +203,8 @@ flwr/simulation/ray_transport/ray_actor.py,sha256=_wv2eP7qxkCZ-6rMyYWnjLrGPBZRxj
206
203
  flwr/simulation/ray_transport/ray_client_proxy.py,sha256=oDu4sEPIOu39vrNi-fqDAe10xtNUXMO49bM2RWfRcyw,6738
207
204
  flwr/simulation/ray_transport/utils.py,sha256=TYdtfg1P9VfTdLMOJlifInGpxWHYs9UfUqIv2wfkRLA,2392
208
205
  flwr/simulation/run_simulation.py,sha256=HiIH6aa_v56NfKQN5ZBd94NyVfaZNyFs43_kItYsQXU,15685
209
- flwr_nightly-1.9.0.dev20240409.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
210
- flwr_nightly-1.9.0.dev20240409.dist-info/METADATA,sha256=TfzMafwI_0a1Frt24FGWgIMD-ufTBvrb2rgpceszReE,15257
211
- flwr_nightly-1.9.0.dev20240409.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
212
- flwr_nightly-1.9.0.dev20240409.dist-info/entry_points.txt,sha256=utu2wybGyYJSTtsB2ktY_gmy-XtMFo9EFZdishX0zR4,320
213
- flwr_nightly-1.9.0.dev20240409.dist-info/RECORD,,
206
+ flwr_nightly-1.9.0.dev20240414.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
207
+ flwr_nightly-1.9.0.dev20240414.dist-info/METADATA,sha256=EQKAZhNg5aUslUrBo5G8dIZOqULNaACDPDDxbLoJXY4,15257
208
+ flwr_nightly-1.9.0.dev20240414.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
209
+ flwr_nightly-1.9.0.dev20240414.dist-info/entry_points.txt,sha256=utu2wybGyYJSTtsB2ktY_gmy-XtMFo9EFZdishX0zR4,320
210
+ flwr_nightly-1.9.0.dev20240414.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- flwr>=1.8, <2.0
2
- numpy>=1.21.0
@@ -1,4 +0,0 @@
1
- flwr[simulation]>=1.8.0
2
- flwr-datasets[vision]==0.0.2
3
- torch==2.2.1
4
- torchvision==0.17.1
@@ -1,4 +0,0 @@
1
- flwr>=1.8, <2.0
2
- flwr-datasets[vision]>=0.0.2, <1.0.0
3
- tensorflow-macos>=2.9.1, !=2.11.1 ; sys_platform == "darwin" and platform_machine == "arm64"
4
- tensorflow-cpu>=2.9.1, !=2.11.1 ; platform_machine == "x86_64"