Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Hellander committed Mar 25, 2024
2 parents 58a5e11 + 7838132 commit ab21e13
Show file tree
Hide file tree
Showing 50 changed files with 2,443 additions and 842 deletions.
116 changes: 87 additions & 29 deletions .ci/tests/examples/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,65 +18,123 @@ def _download_config(output):

def test_api_get_methods():
client = APIClient(host="localhost", port=8092)
status = client.get_controller_status()
assert status
print("Controller status: ", status, flush=True)

events = client.get_events()
assert events
print("Events: ", events, flush=True)
# --- Clients --- #
clients = client.get_clients()
assert clients
print("Clients: ", clients, flush=True)

validations = client.list_validations()
assert validations
print("Validations: ", validations, flush=True)
active_clients = client.get_active_clients()
assert active_clients
print("Active clients: ", active_clients, flush=True)

models = client.get_model_trail()
assert models
print("Models: ", models, flush=True)
clients_count = client.get_clients_count()
assert clients_count
print("Clients count: ", clients_count, flush=True)

clients = client.list_clients()
assert clients
print("Clients: ", clients, flush=True)
# --- Combiners --- #

combiners = client.list_combiners()
combiners = client.get_combiners()
assert combiners
print("Combiners: ", combiners, flush=True)

combiners_count = client.get_combiners_count()
assert combiners_count
print("Combiners count: ", combiners_count, flush=True)

combiner = client.get_combiner("combiner")
assert combiner
print("Combiner: ", combiner, flush=True)

first_model = client.get_initial_model()
assert first_model
print("First model: ", first_model, flush=True)
# --- Controllers --- #

package = client.get_package()
assert package
print("Package: ", package, flush=True)
status = client.get_controller_status()
assert status
print("Controller status: ", status, flush=True)

# --- Models --- #

models = client.get_models()
assert models
print("Models: ", models, flush=True)

models_count = client.get_models_count()
assert models_count
print("Models count: ", models_count, flush=True)

models_from_trail = client.get_model_trail()
assert models_from_trail
print("Models: ", models_from_trail, flush=True)

active_model = client.get_active_model()
assert active_model
print("Active model: ", active_model, flush=True)

# --- Packages --- #

packages = client.get_packages()
assert packages
print("Packages: ", packages, flush=True)

packages_count = client.get_packages_count()
assert packages_count
print("Packages count: ", packages_count, flush=True)

active_package = client.get_active_package()
assert active_package
print("Active package: ", active_package, flush=True)

checksum = client.get_package_checksum()
assert checksum
print("Checksum: ", checksum, flush=True)

rounds = client.list_rounds()
# --- Rounds --- #

rounds = client.get_rounds()
assert rounds
print("Rounds: ", rounds, flush=True)

round = client.get_round(1)
assert round
print("Round: ", round, flush=True)
rounds_count = client.get_rounds_count()
assert rounds_count
print("Rounds count: ", rounds_count, flush=True)

# --- Sessions --- #

sessions = client.list_sessions()
sessions = client.get_sessions()
assert sessions
print("Sessions: ", sessions, flush=True)

sessions_count = client.get_sessions_count()
assert sessions_count
print("Sessions count: ", sessions_count, flush=True)

# --- Statuses --- #

statuses = client.get_statuses()
assert statuses
print("Statuses: ", statuses, flush=True)

statuses_count = client.get_statuses_count()
assert statuses_count
print("Statuses count: ", statuses_count, flush=True)

# --- Validations --- #

validations = client.get_validations()
assert validations
print("Validations: ", validations, flush=True)

validations_count = client.get_validations_count()
assert validations_count
print("Validations count: ", validations_count, flush=True)


if __name__ == '__main__':

client = APIClient(host="localhost", port=8092)
fire.Fire({
'set_seed': client.set_initial_model,
'set_package': client.set_package,
'set_seed': client.set_active_model,
'set_package': client.set_active_package,
'start_session': client.start_session,
'get_client_config': _download_config,
'test_api_get_methods': test_api_get_methods,
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
},
"python.linting.enabled": true,
"python.linting.flake8Enabled": true,
Expand Down
93 changes: 41 additions & 52 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
.. figure:: https://thumb.tildacdn.com/tild6637-3937-4565-b861-386330386132/-/resize/560x/-/format/webp/FEDn_logo.png
:alt: FEDn logo

.. image:: https://github.com/scaleoutsystems/fedn/actions/workflows/integration-tests.yaml/badge.svg
:target: https://github.com/scaleoutsystems/fedn/actions/workflows/integration-tests.yaml
Expand All @@ -10,73 +8,77 @@
.. image:: https://readthedocs.org/projects/fedn/badge/?version=latest&style=flat
:target: https://fedn.readthedocs.io

FEDn is a modular and model agnostic framework for
federated machine learning. FEDn is designed to scale from pseudo-distributed
development on your laptop to real-world production setups in geographically distributed environments.
FEDn
--------

FEDn empowers developers, researchers, and data scientists to create federated learning applications that seamlessly transition from local proofs-of-concept to real-world distributed deployments. Develop your federated learning use case in a pseudo-local environment, and deploy it to FEDn Studio for real-world Federated Learning without any need for code changes.

Core Features
=============

- **Scalable and resilient.** FEDn is scalable and resilient via a tiered
architecture where multiple aggregation servers (combiners) divide up the work to coordinate clients and aggregate models.
Benchmarks show high performance both for thousands of clients in a cross-device
setting and for large model updates in a cross-silo setting.
FEDn has the ability to recover from failure in all critical components.

- **Security**. FEDn is built using secure industry standard communication protocols (gRPC). A key feature is that
clients do not have to expose any ingress ports.
- **Scalable and resilient.** FEDn facilitates the coordination of clients and model aggregation through multiple aggregation servers sharing the workload. This design makes the framework highly scalable, accommodating large numbers of clients. The system is engineered to seamlessly recover from failures, ensuring robust deployment in production environments. Furthermore, FEDn adeptly manages asynchronous federated learning scenarios, accommodating clients that may connect or drop out during training.

- **Track events and training progress in real-time**. FEDn tracks events for clients and aggregation servers, logging to MongoDB. This
helps developers monitor traning progress in real-time, and to troubleshoot the distributed computation.
Tracking and model validation data can easily be retrieved using the API enabling development of custom dashboards and visualizations.
- **Security**. FL clients do not need to open any ingress ports, facilitating real-world deployments across a wide variety of settings. Additionally, FEDn utilizes secure, industry-standard communication protocols and supports token-based authentication for FL clients, enhancing security and ease of integration in diverse environments.

- **Flexible handling of asynchronous clients**. FEDn supports flexible experimentation
with clients coming in and dropping out during training sessions. Extend aggregators to experiment
with different strategies to handle so called stragglers.
- **Track events and training progress in real-time**. Extensive event logging and distributed tracing enable developers to monitor experiments in real-time, simplifying troubleshooting and auditing processes. Machine learning validation metrics from clients can be accessed via the API, allowing for flexible analysis of federated experiments.

- **ML-framework agnostic**. Model updates are treated as black-box
computations. This means that it is possible to support any
ML model type or framework. Support for Keras and PyTorch is
- **ML-framework agnostic**. FEDn is compatible with all major ML frameworks. Examples for Keras, PyTorch and scikit-learn are
available out-of-the-box.

From development to real-world FL:

- Develop a FEDn project in a local development environment, and then deploy it to FEDn Studio
- The FEDn server-side as a managed, production-grade service on Kubernetes.
- Token-based authentication for FL clients
- Role-based access control (RBAC)
- REST API
- Dashboard for orchestrating runs, visualizing and downloading results
- Admin dashboard for managing and scaling the FEDn network
- Collaborate with other data-scientists in a shared workspace.
- Cloud or on-premise deployment

Getting started

Getting started with FEDn
===============

The best way to get started is to take the quickstart tutorial:

- `Quickstart PyTorch <https://fedn.readthedocs.io/en/latest/quickstart.html>`__
- `Quickstart <https://fedn.readthedocs.io/en/latest/quickstart.html>`__

Documentation
=============
You will find more details about the architecture, compute package and how to deploy FEDn fully distributed in the documentation:

More details about the architecture, deployment, and how to develop your own application and framework extensions (such as custom aggregators) are found in the documentation:

- `Documentation <https://fedn.readthedocs.io>`__
- `Paper <https://arxiv.org/abs/2103.00148>`__


FEDn Studio
Deploying a project to FEDn Studio
===============
Scaleout also develops FEDn Studio, a web application that extends the FEDn SDK with a UI, production-grade deployment of the FEDn server side on Kubernetes, user authentication/authorization, client identity/API-token management, and project-based multitenancy for segmenting work and resources into collaboration workspaces. FEDn Studio is available as a fully managed service.
There is also additional tooling and charts for self-managed deployment on Kubernetes including integration with several projects from the cloud native landscape.
See `FEDn Framework <https://www.scaleoutsystems.com/framework>`__ for more information.

Studio offers a production-grade deployment of the FEDn server-side infrastructure on Kubernetes. With Studio, you can also manage token-based authentication for clients and collaborate with other users in joint project workspaces. In addition to a REST API, Studio features intuitive dashboards that allows you to orchestrate FL experiments and visualize and manage global models, event logs and metrics. These features enhance your ability to monitor and analyze federated learning projects. Studio is available as-a service hosted by Scaleout and one project is provided for free for testing and research.

Making contributions
====================
- `Register for a project in Studio <https://studio.scaleoutsystems.com/signup/>`__
- `Deploy you project to FEDn Studio <https://guide.scaleoutsystems.com/#/docs>`__

All pull requests will be considered and are much appreciated. Reach out
to one of the maintainers if you are interested in making contributions,
and we will help you find a good first issue to get you started. For
more details please refer to our `contribution
guidelines <https://github.com/scaleoutsystems/fedn/blob/develop/CONTRIBUTING.md>`__.
Options and charts are also available for self-managed deployment of FEDn Studio, reach out to the Scaleout team for more information.

Community support

Support
=================

Community support in available in our `Discord
server <https://discord.gg/KMg4VwszAd>`__.

Options are also available for `Enterprise support <https://www.scaleoutsystems.com/start#pricing>`__.

Making contributions
====================

All pull requests will be considered and are much appreciated. For
more details please refer to our `contribution
guidelines <https://github.com/scaleoutsystems/fedn/blob/develop/CONTRIBUTING.md>`__.

Citation
========

Expand All @@ -91,24 +93,11 @@ If you use FEDn in your research, please cite:
year={2021}
}

Organizational collaborators, contributors and supporters
=========================================================

|FEDn logo| |UU logo| |AI Sweden logo| |Zenseact logo| |Scania logo|

License
=======

FEDn is licensed under Apache-2.0 (see `LICENSE <LICENSE>`__ file for
full information).

.. |FEDn logo| image:: https://github.com/scaleoutsystems/fedn/raw/master/docs/img/logos/Scaleout.png
:width: 15%
.. |UU logo| image:: https://github.com/scaleoutsystems/fedn/raw/master/docs/img/logos/UU.png
:width: 15%
.. |AI Sweden logo| image:: https://github.com/scaleoutsystems/fedn/raw/master/docs/img/logos/ai-sweden-logo.png
:width: 15%
.. |Zenseact logo| image:: https://github.com/scaleoutsystems/fedn/raw/master/docs/img/logos/zenseact-logo.png
:width: 15%
.. |Scania logo| image:: https://github.com/scaleoutsystems/fedn/raw/master/docs/img/logos/Scania.png
:width: 15%
Use of FEDn Studio (SaaS) is subject to the `Terms of Use <https://www.scaleoutsystems.com/terms>`__.
90 changes: 90 additions & 0 deletions docs/auth.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
.. _auth-label:

Authentication and Authorization (RBAC)
=============================================
.. warning:: The FEDn RBAC system is an experimental feature and may change in the future.

FEDn supports Role-Based Access Control (RBAC) for controlling access to the FEDn API and gRPC endpoints. The RBAC system is based on JSON Web Tokens (JWT) and is implemented using the `jwt` package. The JWT tokens are used to authenticate users and to control access to the FEDn API.
There are two types of JWT tokens used in the FEDn RBAC system:
- Access tokens: Used to authenticate users and to control access to the FEDn API.
- Refresh tokens: Used to obtain new access tokens when the old ones expire.

.. note:: Please note that the FEDn RBAC system is not enabled by default and does not issue JWT tokens. It is used to integrate with external authentication and authorization systems such as FEDn Studio.

FEDn RBAC system is by default configured with four types of roles:
- `admin`: Has full access to the FEDn API. This role is used to manage the FEDn network using the API client or the FEDn CLI.
- `combiner`: Has access to the /add_combiner endpoint in the API.
- `client`: Has access to the /add_client endpoint in the API and various gRPC endpoint to participate in federated learning sessions.

A full list of the "roles to endpoint" mappings for gRPC can be found in the `fedn/network/grpc/auth.py`. For the API, the mappings are defined using custom decorators defined in `fedn/network/api/auth.py`.

.. note:: The roles are handled by a custom claim in the JWT token called `role`. The claim is used to control access to the FEDn API and gRPC endpoints.

To enable the FEDn RBAC system, you need to set the following environment variables in the controller and combiner:

.. envvar:: FEDN_JWT_SECRET_KEY
:type: str
:required: yes
:default: None
:description: The secret key used for JWT token encryption.

.. envvar:: FEDN_JWT_ALGORITHM
:type: str
:required: no
:default: "HS256"
:description: The algorithm used for JWT token encryption.

.. envvar:: FEDN_AUTH_SCHEME
:type: str
:required: no
:default: "Token"
:description: The authentication scheme used in the FEDn API and gRPC interceptors.

For further fexibility, you can also set the following environment variables:

.. envvar:: FEDN_CUSTOM_URL_PREFIX
:type: str
:required: no
:default: None
:description: Add a custom URL prefix used in the FEDn API, such as /internal or /v1.

.. envvar:: FEDN_AUTH_WHITELIST_URL
:type: str
:required: no
:default: None
:description: A URL patterns to the API that should be excluded from the FEDn RBAC system. For example /internal (to enable internal API calls).

.. envvar:: FEDN_JWT_CUSTOM_CLAIM_KEY
:type: str
:required: no
:default: None
:description: The custom claim key used in the JWT token.

.. envvar:: FEDN_JWT_CUSTOM_CLAIM_VALUE
:type: str
:required: no
:default: None
:description: The custom claim value used in the JWT token.


For the client you need to set the following environment variables:

.. envvar:: FEDN_JWT_ACCESS_TOKEN
:type: str
:required: yes
:default: None
:description: The access token used to authenticate the client to the FEDn API.

.. envvar:: FEDN_JWT_REFRESH_TOKEN
:type: str
:required: no
:default: None
:description: The refresh token used to obtain new access tokens when the old ones expire.

.. envvar:: FEDN_AUTH_SCHEME
:type: str
:required: no
:default: "Token"
:description: The authentication scheme used in the FEDn API and gRPC interceptors.

You can also use `--token` flags in the FEDn CLI to set the access token.
Loading

0 comments on commit ab21e13

Please sign in to comment.