# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['dpsa4flower']

package_data = \
{'': ['*']}

install_requires = \
['dataclass-wizard>=0.22.2,<0.23.0',
 'dpsa4fl-bindings>=0.1.3,<0.2.0',
 'flwr>=1.4.0,<2.0.0',
 'numpy>=1.24.3,<2.0.0']

setup_kwargs = {
    'name': 'dpsa4flower',
    'version': '0.1.0',
    'description': 'A server and client to use the flower framework with DPSA.',
    'long_description': '# dpsa4flower\nServer and client to use the [flower framework](https://flower.dev/) for differentially private federated learning with secure aggregation.\n\nMade to be used with the [dpsa infrastructure](https://github.com/dpsa-project/overview), head there for an explanation of the system\'s participants and properties. Setup of additional aggregation servers is required, head [here](https://github.com/dpsa-project/dpsa4fl-testing-infrastructure) for instructions.\n\n## Installation\nTo install, you require the following packages:\n- python version 3.9 or higher.\n- [poetry](https://python-poetry.org/) package manager for python\n\nOnce you have those, go ahead and clone this repository:\n```\n> git clone https://github.com/dpsa-project/dpsa4flower.git\n```\nEnter the new directory:\n```\n> cd dpsa4flower\n```\nUse poetry to create a virtualenv and install all dependencies:\n```\n> poetry shell\n> poetry install\n```\nYou\'re ready to use our classes now. Note that to actually run a learning task, you will need to provide locations at which two seperate dpsa4fl aggregation servers are running. See [here](https://github.com/dpsa-project/dpsa4fl-testing-infrastructure) for instructions or check out our example project.\n\n## Example code\nThere is a [repo](https://github.com/dpsa-project/dpsa4fl-example-project) containing an example implementation learning the CIFAR task using a torch model, where learning is federated using flower with differential privacy and secure aggregation.\n\n## Classes\nThis package exposes two classes, one for the server and one for the client.\n### `DPSAServer(model_size, privacy_parameter, granularity, aggregator1_location, aggregator2_location, client_manager, strategy)`\n\nThe [dpsa4flower server class](https://github.com/dpsa-project/dpsa4flower/blob/3f1becb09bb79dfe26f9ee959114cf6c36a31dbb/dpsa_flower/dpsa_server.py#L40) extends the [flower server class](https://flower.dev/docs/apiref-flwr.html#module-flwr.server) with the necessities for using DPSA for aggregation. It handles configuration of the aggregator servers, reshaping of the collected aggregation results, and redistributing the updates to the clients. Construction requires the following parameters as keyword arguments:\n\n- `model_size: int` The number of parameters of the model to be trained.\n- `privacy_parameter: float` The desired privacy per learning step. One aggregation step will\n    be `1/2*privacy_parameter^2` zero-concentrated differentially private\n    for each client.\n- `granularity: int` The resolution of the fixed-point encoding used for secure aggregation.\n    A larger value will result in a less lossy representation and more\n    communication and computation overhead. Currently, 16, 32 and 64 bit are\n    supported.\n- `aggregator1_location: str` Location of the first aggregator server in URL format including the port.\n    For example, for a server running locally: "http://127.0.0.1:9991"\n- `aggregator2_location: str` Location of the second aggregator server in URL format including the port.\n    For example, for a server running locally: "http://127.0.0.1:9992"\n- `client_manager: flwr.server.ClientManager` A flower client manager to manage connected clients.\n- `strategy: Optional[flwr.server.strategy.Strategy]` A flower strategy for the server to use. It will be wrapped replacing the `configure_fit` and `aggregate_fit` methods with ones that interact with the dpsa infrastructure.\n\nAn example construction of a dpsa4flower server object would look like this:\n```python\ndpsa4flower.DPSAServer(\n        model_size = 62006,\n        privacy_parameter = 30,\n        granularity = 32,\n        aggregator1_location = "http://127.0.0.1:9981",\n        aggregator2_location = "http://127.0.0.1:9982",\n        client_manager=flwr.server.SimpleClientManager(),\n)\n```\nThe created object can then be used to start a flower server using [`flwr.server.start_server`](https://flower.dev/docs/apiref-flwr.html#server-start-server) as usual.\n\n### `DPSANumPyClient(max_privacy_per_round, aggregator1_location, aggregator2_location, client, allow_evaluate)`\nThe [dpsa4flower client class](https://github.com/dpsa-project/dpsa4flower/blob/3f1becb09bb79dfe26f9ee959114cf6c36a31dbb/dpsa_flower/dpsa_numpy_client.py#L19) implements the [`NumPyClient`](https://flower.dev/docs/apiref-flwr.html#numpyclient) interface provided by flower. It\'s a wrapper for existing `NumPyClient`s adding secure aggregation and differential privacy. The wrapped client is used for local training, results are then submitted to the secure aggregation infrastructure in an encrypted fashion. The constructor requires the following parameters as keyword arguments:\n \n- `max_privacy_per_round: float` The maximal zero-contentrated differential privacy budget allowed to be spent on a single round of training. If the selected server offers a weaker guarantee, no data will be submitted and an exception will be raised.\n- `aggregator1_location: str` Location of the first aggregator server in URL format including the port. For example, for a server running locally: "http://127.0.0.1:9991"\n- `aggregator2_location: str` Location of the second aggregator server in URL format including the port. For example, for a server running locally: "http://127.0.0.1:9992"\n- `client: flower.client.numpy_client.NumPyClient` The NumPyClient used for executing the local learning tasks.\n- `allow_evaluate: bool` Evaluation is a privacy-relevant operation on the client dataset. If this flag is set to `False`, evaluation always reports infinite loss and zero accuracy to the server. Otherwise, the evaluation function of the wrapped client will be used and the results will be released to the server, potentially compromising privacy. Defaults to `False`.\n\nAn example construction of a dpsa4flower client object would look like this:\n```python\ndpsa4flower.DPSANumPyClient(\n    max_privacy_per_round = 30,\n    aggregator1_location = "http://127.0.0.1:9981",\n    aggregator2_location = "http://127.0.0.1:9982",\n    client = FlowerClient()\n)\n```\nwhere `FlowerClient` is some [`NumPyClient`](https://flower.dev/docs/apiref-flwr.html#numpyclient) of your choice. It can then be started using [`flwr.client.start_numpy_client`](https://flower.dev/docs/apiref-flwr.html#flwr.client.start_numpy_client) as usual.\n\n## What\'s going on\nWhen using our classes in the setup described (and used in the example project), the training procedure takes place as described in this diagram:\n\n\n```\n                                             gradient sum\n          ┌───────────────────────────────────────────────────────────────────────────────┐\n          │                             (differentially private)                          │\n          │                                                                               │\n          │                                                                               │\n          │                                                                               │\n          │                                                                               │\n          │             gradient shares                                                   │\n          │              (ciphertext)                                                     │\n  ┌───────▼─────────┬────────────────────┐                                                │\n  │ DPSANumPyClient │                    │ ┌──────────────┐                               │\n  └─────────────────┴────────────────┐   └─►              │                               │\n                                     │     │ Aggregator 1 ├───┐                           │\n                                 ┌───)─────►              │   │                           │\n                                 │   │     └──────────────┘   │                   ┌───────┴───────┐\n          .                      │   │                        │    gradient sum   │               │\n          .                      │   │                        ├───────────────────►  DPSAServer   │\n          .                      │   │                        │  (differentially  │               │\n                                 │   │     ┌──────────────┐   │      private)     └───────────────┘\n                                 │   └─────►              │   │\n                                 │         │ Aggregator 2 ├───┘\n  ┌─────────────────┬────────────┘   ┌─────►              │\n  │ DPSANumPyClient │                │     └──────────────┘\n  └─────────────────┴────────────────┘\n                     gradient shares\n                      (ciphertext)\n\n\n\n     flower clients                     dpsa4fl infrastructure                     flower server\n     --------------                     ----------------------                     -------------\ncompute gradients locally          checks if clipping was done properly,        collects aggregate,\n   on sensitive data,               computes aggregate on ciphertext,           distributes updates\nclip to norm 1 and submit          adds noise for differential privacy.         back to the clients\n                                     ciphertext can not be decrypted\n                                     if the servers don\'t collaborate\n```\n',
    'author': 'Maxim Urschumzew',
    'author_email': 'u.maxim@live.de',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'None',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
