Skip to content

Commit

Permalink
Merge branch 'master' into feature/SK-732
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Hellander committed Apr 26, 2024
2 parents 90fb195 + 20c1767 commit 9ec1d02
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 22 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/push-to-pypi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Publish Python distribution to PyPI

on:
release:
types: [created]

jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"

- name: Install pypa/build
run: python -m pip install build
working-directory: ./fedn

- name: Build package
run: python -m build
working-directory: ./fedn

- name: Publish to Test PyPI
uses: pypa/gh-action-pypi-publish@v1.8.14
with:
user: __token__
password: ${{ secrets.PYPI_TOKEN }}
packages_dir: fedn/dist
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
author = 'Scaleout Systems AB'

# The full version, including alpha/beta/rc tags
release = '0.9.0'
release = '0.9.1'

# Add any Sphinx extension module names here, as strings
extensions = [
Expand Down
9 changes: 5 additions & 4 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,14 @@ You are now ready to start training the model using the APIClient:
.. code:: python
>>> ...
>>> client.start_session(session_id="test-session", rounds=3)
>>> client.start_session(id="test-session", rounds=3)
# Wait for training to complete, when controller is idle:
>>> client.get_controller_status()
# Show model trail:
>>> client.get_model_trail()
# Show model performance:
>>> client.get_validations()
>>> models = client.get_model_trail()
# Show performance of latest global model:
>>> model_id = models[-1]['model']
>>> validations = client.get_validations(model_id=model_id)
Please see :py:mod:`fedn.network.api` for more details on the APIClient.
Expand Down
4 changes: 2 additions & 2 deletions examples/async-clients/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ pip install -r requirements.txt
Create the compute package and seed model:
```
tar -czvf package.tgz client
fedn package create --path client
```
```
python client/entrypoint init_seed
fedn run build --path client
```
You will now have a file 'seed.npz' in the directory.
Expand Down
6 changes: 4 additions & 2 deletions examples/async-clients/client/fedn.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
entry_points:
build:
command: python entrypoint.py init_seed ../seed.npz
train:
command: python entrypoint.py train $ENTRYPOINT_OPTS
command: python entrypoint.py train
validate:
command: python entrypoint.py validate $ENTRYPOINT_OPTS
command: python entrypoint.py validate
4 changes: 3 additions & 1 deletion examples/async-clients/run_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@

from fedn.network.clients.client import Client

# Use with a local deployment
settings = {
'DISCOVER_HOST': '127.0.0.1',
'DISCOVER_PORT': 8092,
'TOKEN': None,
'N_CLIENTS': 10,
'N_CYCLES': 100,
'CLIENTS_MAX_DELAY': 10,
'CLIENTS_ONLINE_FOR_SECONDS': 120
}

client_config = {'discover_host': settings['DISCOVER_HOST'], 'discover_port': settings['DISCOVER_PORT'], 'token': None, 'name': 'testclient',
client_config = {'discover_host': settings['DISCOVER_HOST'], 'discover_port': settings['DISCOVER_PORT'], 'token': settings['TOKEN'], 'name': 'testclient',
'client_id': 1, 'remote_compute_context': True, 'force_ssl': False, 'dry_run': False, 'secure': False,
'preshared_cert': False, 'verify': False, 'preferred_combiner': False,
'validator': True, 'trainer': True, 'init': None, 'logfile': 'test.log', 'heartbeat_interval': 2,
Expand Down
2 changes: 1 addition & 1 deletion examples/flower-client/README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FEDn Project: Flower ClientApps in FEDn
---------------------------------------

This example demonstrates how to run a Flower 'ClientApp' on FEDn.
This example demonstrates how to run a Flower 'ClientApp' on FEDn. Sign up to FEDn Studio for a quick and easy way to set up all the backend services: https://fedn.scaleoutsystems.com/signup/ (optional).

The FEDn compute package 'client/entrypoint'
uses a built-in Flower compatibiltiy adapter for convenient wrapping of the Flower client.
Expand Down
18 changes: 9 additions & 9 deletions fedn/fedn/network/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def get_active_clients(self, combiner_id: str = None, n_max: int = None):
if n_max:
_headers['X-Limit'] = str(n_max)

response = requests.get(self._get_url_api_v1('clients'), params=_params, verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('clients/'), params=_params, verify=self.verify, headers=_headers)

_json = response.json()

Expand Down Expand Up @@ -168,7 +168,7 @@ def get_combiners(self, n_max: int = None):
if n_max:
_headers['X-Limit'] = str(n_max)

response = requests.get(self._get_url_api_v1('combiners'), verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('combiners/'), verify=self.verify, headers=_headers)

_json = response.json()

Expand Down Expand Up @@ -236,7 +236,7 @@ def get_models(self, session_id: str = None, n_max: int = None):
if n_max:
_headers['X-Limit'] = str(n_max)

response = requests.get(self._get_url_api_v1('models'), params=_params, verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('models/'), params=_params, verify=self.verify, headers=_headers)

_json = response.json()

Expand All @@ -263,7 +263,7 @@ def get_active_model(self):
_headers = self.headers.copy()
_headers['X-Limit'] = "1"

response = requests.get(self._get_url_api_v1('models'), verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('models/'), verify=self.verify, headers=_headers)
_json = response.json()

if "result" in _json and len(_json["result"]) > 0:
Expand Down Expand Up @@ -362,7 +362,7 @@ def get_packages(self, n_max: int = None):
if n_max:
_headers['X-Limit'] = str(n_max)

response = requests.get(self._get_url_api_v1('packages'), verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('packages/'), verify=self.verify, headers=_headers)

_json = response.json()

Expand Down Expand Up @@ -467,7 +467,7 @@ def get_rounds(self, n_max: int = None):
if n_max:
_headers['X-Limit'] = str(n_max)

response = requests.get(self._get_url_api_v1('rounds'), verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('rounds/'), verify=self.verify, headers=_headers)

_json = response.json()

Expand Down Expand Up @@ -515,7 +515,7 @@ def get_sessions(self, n_max: int = None):
if n_max:
_headers['X-Limit'] = str(n_max)

response = requests.get(self._get_url_api_v1('sessions'), verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('sessions/'), verify=self.verify, headers=_headers)

_json = response.json()

Expand Down Expand Up @@ -667,7 +667,7 @@ def get_statuses(self, session_id: str = None, event_type: str = None, sender_na
if n_max:
_headers['X-Limit'] = str(n_max)

response = requests.get(self._get_url_api_v1('statuses'), params=_params, verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('statuses/'), params=_params, verify=self.verify, headers=_headers)

_json = response.json()

Expand Down Expand Up @@ -761,7 +761,7 @@ def get_validations(
if n_max:
_headers['X-Limit'] = str(n_max)

response = requests.get(self._get_url_api_v1('validations'), params=_params, verify=self.verify, headers=_headers)
response = requests.get(self._get_url_api_v1('validations/'), params=_params, verify=self.verify, headers=_headers)

_json = response.json()

Expand Down
2 changes: 1 addition & 1 deletion fedn/fedn/network/combiner/combiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def _list_active_clients(self, channel):
if (now - then) < timedelta(seconds=10):
clients["active_clients"].append(client)
# If client has changed status, update statestore
if status == "offline":
if status != "online":
self.clients[client]["status"] = "online"
clients["update_active_clients"].append(client)
else:
Expand Down
4 changes: 3 additions & 1 deletion fedn/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

setup(
name='fedn',
version='0.9.0',
version='0.9.1',
description="""Scaleout Federated Learning""",
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
author='Scaleout Systems AB',
author_email='contact@scaleoutsystems.com',
url='https://www.scaleoutsystems.com',
Expand Down

0 comments on commit 9ec1d02

Please sign in to comment.