Skip to content

Commit

Permalink
Merge branch 'main' into fds-add-vertical-size-partitioner
Browse files Browse the repository at this point in the history
  • Loading branch information
jafermarq authored Dec 17, 2024
2 parents fc2aa81 + 0c838d7 commit c85f4b7
Show file tree
Hide file tree
Showing 24 changed files with 630 additions and 191 deletions.
1 change: 1 addition & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets. AWS_SECRET_ACCESS_KEY }}
DOCS_BUCKET: flower.ai
run: |
cp -r doc/build/html/v* framework/docs/build/html
aws s3 sync --delete --exclude ".*" --exclude "v/*" --cache-control "no-cache" ./framework/docs/build/html/ s3://${{ env.DOCS_BUCKET }}/docs/framework
aws s3 sync --delete --exclude ".*" --exclude "v/*" --cache-control "no-cache" ./baselines/docs/build/html/ s3://${{ env.DOCS_BUCKET }}/docs/baselines
aws s3 sync --delete --exclude ".*" --exclude "v/*" --cache-control "no-cache" ./examples/docs/build/html/ s3://${{ env.DOCS_BUCKET }}/docs/examples
Expand Down
2 changes: 1 addition & 1 deletion datasets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Create **custom partitioning schemes** or choose from the **implemented [partiti
* Exponential partitioning `ExponentialPartitioner(num_partitions)`
* more to come in the future releases (contributions are welcome).
<p align="center">
<img src="./doc/source/_static/readme/comparison_of_partitioning_schemes.png" alt="Comparison of partitioning schemes."/>
<img src="./docs/source/_static/readme/comparison_of_partitioning_schemes.png" alt="Comparison of partitioning schemes."/>
<br>
<em>Comparison of Partitioning Schemes on CIFAR10</em>
</p>
Expand Down
4 changes: 2 additions & 2 deletions datasets/dev/format.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ echo "Formatting done: Python"

# Notebooks
echo "Formatting started: Notebooks"
python -m black --ipynb -q doc/source/*.ipynb
python -m black --ipynb -q docs/source/*.ipynb
KEYS="metadata.celltoolbar metadata.language_info metadata.toc metadata.notify_time metadata.varInspector metadata.accelerator metadata.vscode cell.metadata.id cell.metadata.heading_collapsed cell.metadata.hidden cell.metadata.code_folding cell.metadata.tags cell.metadata.init_cell cell.metadata.vscode cell.metadata.pycharm"
python -m nbstripout --keep-output doc/source/*.ipynb --extra-keys "$KEYS"
python -m nbstripout --keep-output docs/source/*.ipynb --extra-keys "$KEYS"
echo "Formatting done: Notebooks"
22 changes: 13 additions & 9 deletions e2e/e2e-bare/e2e_bare/client_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np

from flwr.client import ClientApp, NumPyClient, start_client
from flwr.common import ConfigsRecord, Context
from flwr.common import ConfigsRecord, Context, RecordSet

SUBSET_SIZE = 1000
STATE_VAR = "timestamp"
Expand All @@ -15,23 +15,24 @@

# Define Flower client
class FlowerClient(NumPyClient):
def __init__(self, state: RecordSet):
self.state = state

def get_parameters(self, config):
return model_params

def _record_timestamp_to_state(self):
"""Record timestamp to client's state."""
t_stamp = datetime.now().timestamp()
value = str(t_stamp)
if STATE_VAR in self.context.state.configs_records.keys():
value = self.context.state.configs_records[STATE_VAR][STATE_VAR] # type: ignore
if STATE_VAR in self.state.configs_records.keys():
value = self.state.configs_records[STATE_VAR][STATE_VAR] # type: ignore
value += f",{t_stamp}"

self.context.state.configs_records[STATE_VAR] = ConfigsRecord(
{STATE_VAR: value}
)
self.state.configs_records[STATE_VAR] = ConfigsRecord({STATE_VAR: value})

def _retrieve_timestamp_from_state(self):
return self.context.state.configs_records[STATE_VAR][STATE_VAR]
return self.state.configs_records[STATE_VAR][STATE_VAR]

def fit(self, parameters, config):
model_params = parameters
Expand All @@ -52,7 +53,7 @@ def evaluate(self, parameters, config):


def client_fn(context: Context):
return FlowerClient().to_client()
return FlowerClient(context.state).to_client()


app = ClientApp(
Expand All @@ -61,4 +62,7 @@ def client_fn(context: Context):

if __name__ == "__main__":
# Start Flower client
start_client(server_address="127.0.0.1:8080", client=FlowerClient().to_client())
start_client(
server_address="127.0.0.1:8080",
client=FlowerClient(state=RecordSet()).to_client(),
)
20 changes: 11 additions & 9 deletions e2e/e2e-pytorch/e2e_pytorch/client_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from tqdm import tqdm

from flwr.client import ClientApp, NumPyClient, start_client
from flwr.common import ConfigsRecord, Context
from flwr.common import ConfigsRecord, Context, RecordSet

# #############################################################################
# 1. Regular PyTorch pipeline: nn.Module, train, test, and DataLoader
Expand Down Expand Up @@ -90,23 +90,25 @@ def load_data():

# Define Flower client
class FlowerClient(NumPyClient):

def __init__(self, state: RecordSet):
self.state = state

def get_parameters(self, config):
return [val.cpu().numpy() for _, val in net.state_dict().items()]

def _record_timestamp_to_state(self):
"""Record timestamp to client's state."""
t_stamp = datetime.now().timestamp()
value = str(t_stamp)
if STATE_VAR in self.context.state.configs_records.keys():
value = self.context.state.configs_records[STATE_VAR][STATE_VAR] # type: ignore
if STATE_VAR in self.state.configs_records.keys():
value = self.state.configs_records[STATE_VAR][STATE_VAR] # type: ignore
value += f",{t_stamp}"

self.context.state.configs_records[STATE_VAR] = ConfigsRecord(
{STATE_VAR: value}
)
self.state.configs_records[STATE_VAR] = ConfigsRecord({STATE_VAR: value})

def _retrieve_timestamp_from_state(self):
return self.context.state.configs_records[STATE_VAR][STATE_VAR]
return self.state.configs_records[STATE_VAR][STATE_VAR]

def fit(self, parameters, config):
set_parameters(net, parameters)
Expand Down Expand Up @@ -137,7 +139,7 @@ def set_parameters(model, parameters):


def client_fn(context: Context):
return FlowerClient().to_client()
return FlowerClient(context.state).to_client()


app = ClientApp(
Expand All @@ -149,5 +151,5 @@ def client_fn(context: Context):
# Start Flower client
start_client(
server_address="127.0.0.1:8080",
client=FlowerClient().to_client(),
client=FlowerClient(state=RecordSet()).to_client(),
)
2 changes: 1 addition & 1 deletion examples/quickstart-pandas/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ authors = [
dependencies = [
"flwr[simulation]>=1.13.1",
"flwr-datasets[vision]>=0.3.0",
"numpy==1.24.4",
"numpy>=1.26.0",
"pandas==2.0.0",
]

Expand Down
2 changes: 1 addition & 1 deletion examples/vertical-fl/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ license = "Apache-2.0"
dependencies = [
"flwr[simulation]>=1.13.1",
"flwr-datasets>=0.3.0",
"numpy==1.24.4",
"pandas==2.0.3",
"numpy>=1.26.0",
"scikit-learn==1.3.2",
"torch==2.1.0",
]
Expand Down
15 changes: 8 additions & 7 deletions framework/docs/source/how-to-run-flower-on-azure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ Run Flower on Azure

.. note::

There are many ways to deploy Flower on Microst Azure. The instructions provided in
this guide is just a basic walkthrough, step-by-step guide on how to quickly setup
and run a Flower application on a Federated Learning environment on Microst Azure.
There are many ways to deploy Flower on Microsoft Azure. The instructions provided
in this guide is just a basic walkthrough, step-by-step guide on how to quickly
setup and run a Flower application on a Federated Learning environment on Microsoft
Azure.

In this how-to guide, we want to create a Federated Learning environment on Microst
In this how-to guide, we want to create a Federated Learning environment on Microsoft
Azure using three Virtual Machines (VMs). From the three machines, one machine will be
used as the Federation server and two as the Federation clients. Our goal is to create a
Flower federation on Microst Azure where we can run Flower apps from our local machine,
e.g., laptop.
Flower federation on Microsoft Azure where we can run Flower apps from our local
machine, e.g., laptop.

On the Federation server VM we will deploy the long-running Flower server
(``SuperLink``) and on the two Federation client VMs we will deploy the long-running
Expand All @@ -43,7 +44,7 @@ networking rules to allow cross-VM communication.
VM Create
~~~~~~~~~

Assuming we are already inside the Microst Azure portal, we navigate to the ``Create``
Assuming we are already inside the Microsoft Azure portal, we navigate to the ``Create``
page and we select ``Azure virtual machine``. In the new page, for each VM we edit the
properties as follows:

Expand Down
194 changes: 194 additions & 0 deletions framework/docs/source/how-to-use-cli-json-output.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
Use CLI JSON output
===================

The `Flower CLIs <ref-api-cli.html>`_ come with a built-in JSON output mode. This mode
is useful when you want to consume the output of a Flower CLI programmatically. For
example, you might want to use the output of the ``flwr`` CLI in a script or a
continuous integration pipeline.

.. note::

The JSON output mode is currently only available when using the Flower CLIs with a
`SuperLink <ref-api-cli.html#flower-superlink>`_. Learn more about the `SuperLink`
in the `Flower Architecture Overview <explanation-flower-architecture.html>`_ page.

In this guide, we'll show you how to specify a JSON output with the ``flwr run``, ``flwr
ls``, and ``flwr stop`` commands. We will also provide examples of the JSON output for
each of these commands.

.. |flwr_run| replace:: ``flwr run``

.. |flwr_ls| replace:: ``flwr ls``

.. |flwr_stop| replace:: ``flwr stop``

.. _flwr_ls: ref-api-cli.html#flwr-ls

.. _flwr_run: ref-api-cli.html#flwr-run

.. _flwr_stop: ref-api-cli.html#flwr-stop

``flwr run`` JSON output
------------------------

The |flwr_run|_ command runs a Flower app from a provided directory. Note that if the
app path argument is not passed to ``flwr run``, the current working directory is used
as the default Flower app directory. By default, executing the ``flwr run`` command
prints the status of the app build and run process as follows:

.. code-block:: bash
$ flwr run
Loading project configuration...
Success
🎊 Successfully built flwrlabs.myawesomeapp.1-0-0.014c8eb3.fab
🎊 Successfully started run 1859953118041441032
To get the output in JSON format, pass an additional ``--format json`` flag:

.. code-block:: bash
$ flwr run --format json
{
"success": true,
"run-id": 1859953118041441032,
"fab-id": "flwrlabs/myawesomeapp",
"fab-name": "myawesomeapp",
"fab-version": "1.0.0",
"fab-hash": "014c8eb3",
"fab-filename": "flwrlabs.myawesomeapp.1-0-0.014c8eb3.fab"
}
The JSON output for ``flwr run`` contains the following fields:

- ``success``: A boolean indicating whether the command was successful.
- ``run-id``: The ID of the run.
- ``fab-id``: The ID of the Flower app.
- ``fab-name``: The name of the Flower app.
- ``fab-version``: The version of the Flower app.
- ``fab-hash``: The short hash of the Flower app.
- ``fab-filename``: The filename of the Flower app.

If the command fails, the JSON output will contain two fields, ``success`` with the
value of ``false`` and ``error-message``. For example, if the command fails to find the
name of the federation on the SuperLink, the output will look like this:

.. _json_error_output:

.. code-block:: bash
$ flwr run --format json
{
"success": false,
"error-message": "Loading project configuration... \nSuccess\n There is no `[missing]` federation declared in the `pyproject.toml`.\n The following federations were found:\n\nfed-existing-1\nfed-existing-2\n\n"
}
``flwr ls`` JSON output
-----------------------

The |flwr_ls|_ command lists all the runs in the current project. Similar to ``flwr
run``, if the app path argument is not passed to ``flwr ls``, the current working
directory is used as the Flower app directory. By default, the command list the details
of all runs in a Flower federation in a tabular format:

.. code-block:: bash
$ flwr ls
Loading project configuration...
Success
📄 Listing all runs...
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Run ID ┃ FAB ┃ Status ┃ Elapsed ┃ Created At ┃ Running At ┃ Finished At ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ 185995311804 │ flwrlabs/my… │ finished:co… │ 00:00:55 │ 2024-12-16 │ 2024-12-16 │ 2024-12-16 │
│ 1441032 │ (v1.0.0) │ │ │ 11:12:33Z │ 11:12:33Z │ 11:13:29Z │
├──────────────┼──────────────┼──────────────┼──────────┼──────────────┼──────────────┼─────────────┤
│ 142007406570 │ flwrlabs/my… │ running │ 00:00:05 │ 2024-12-16 │ 2024-12-16 │ N/A │
│ 11601420 │ (v1.0.0) │ │ │ 12:18:39Z │ 12:18:39Z │ │
└──────────────┴──────────────┴──────────────┴──────────┴──────────────┴──────────────┴─────────────┘
To get the output in JSON format, simply pass the ``--format json`` flag:

.. code-block:: bash
$ flwr ls --format json
{
"success": true,
"runs": [
{
"run-id": 1859953118041441032,
"fab-id": "flwrlabs/myawesomeapp1",
"fab-name": "myawesomeapp1",
"fab-version": "1.0.0",
"fab-hash": "014c8eb3",
"status": "finished:completed",
"elapsed": "00:00:55",
"created-at": "2024-12-16 11:12:33Z",
"running-at": "2024-12-16 11:12:33Z",
"finished-at": "2024-12-16 11:13:29Z"
},
{
"run-id": 14200740657011601420,
"fab-id": "flwrlabs/myawesomeapp2",
"fab-name": "myawesomeapp2",
"fab-version": "1.0.0",
"fab-hash": "014c8eb3",
"status": "running",
"elapsed": "00:00:09",
"created-at": "2024-12-16 12:18:39Z",
"running-at": "2024-12-16 12:18:39Z",
"finished-at": "N/A"
},
]
}
The JSON output for ``flwr ls`` contains similar fields as ``flwr run`` with the
addition of the ``status``, ``elapsed``, ``created-at``, ``running-at``, and
``finished-at`` fields. The ``runs`` key contains a list of dictionaries, each
representing a run. The additional fields are:

- ``status``: The status of the run, either pending, starting, running, or finished.
- ``elapsed``: The time elapsed since the run started, formatted as ``HH:MM:SS``.
- ``created-at``: The time the run was created.
- ``running-at``: The time the run started running.
- ``finished-at``: The time the run finished.

All timestamps adhere to ISO 8601, UTC and are formatted as ``YYYY-MM-DD HH:MM:SSZ``.

You can also use the ``--run-id`` flag to list the details for one run. In this case,
the JSON output will have the same structure as above with only one entry in the
``runs`` key. For more details of this command, see the |flwr_ls|_ documentation. If the
command fails, the JSON output will return two fields, ``success`` and
``error-message``, as shown in :ref:`the above example <json_error_output>`. Note that
the content of the error message will be different depending on the error that occurred.

``flwr stop`` JSON output
-------------------------

The |flwr_stop|_ command stops a running Flower app for a provided run ID. Similar to
``flwr run``, if the app path argument is not passed to ``flwr stop``, the current
working directory is used as the Flower app directory. By default, the command prints
the status of the stop process as follows:

.. code-block:: bash
$ flwr stop 1859953118041441032
Loading project configuration...
Success
✋ Stopping run ID 1859953118041441032...
✅ Run 1859953118041441032 successfully stopped.
To get the output in JSON format, simply pass the ``--format json`` flag:

.. code-block:: bash
$ flwr stop 1859953118041441032 --format json
{
"success": true,
"run-id": 1859953118041441032,
}
If the command fails, the JSON output will contain two fields ``success`` with the value
of ``false`` and ``error-message``, as shown in :ref:`the above example
<json_error_output>`. Note that the content of the error message will be different
depending on the error that occurred.
1 change: 1 addition & 0 deletions framework/docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Problem-oriented how-to guides show step-by-step how to achieve a specific goal.
how-to-authenticate-supernodes
how-to-implement-fedbn
how-to-run-flower-on-azure
how-to-use-cli-json-output
docker/index
how-to-upgrade-to-flower-1.0
how-to-upgrade-to-flower-1.13
Expand Down
Loading

0 comments on commit c85f4b7

Please sign in to comment.