Skip to content

Commit

Permalink
First rough attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanhellander committed Nov 30, 2023
1 parent fb1f335 commit e180369
Show file tree
Hide file tree
Showing 15 changed files with 647 additions and 411 deletions.
67 changes: 62 additions & 5 deletions fedn/cli/run_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import yaml

from fedn.common.exceptions import InvalidClientConfig
from fedn.network.api.server import Controller
from fedn.network.clients.client import Client
from fedn.network.combiner.server import Combiner
from fedn.network.dashboard.restservice import (decode_auth_token,
Expand Down Expand Up @@ -134,6 +135,11 @@ def client_cmd(ctx, discoverhost, discoverport, token, name, client_id, local_pa
:return:
"""
remote = False if local_package else True
if not init:
if not discoverhost:
discoverhost = "localhost"
if not discoverport:
discoverport = 8092
config = {'discover_host': discoverhost, 'discover_port': discoverport, 'token': token, 'name': name,
'client_id': client_id, 'remote_compute_context': remote, 'force_ssl': force_ssl, 'dry_run': dry_run, 'secure': secure,
'preshared_cert': preshared_cert, 'verify': verify, 'preferred_combiner': preferred_combiner,
Expand All @@ -155,7 +161,7 @@ def client_cmd(ctx, discoverhost, discoverport, token, name, client_id, local_pa
@click.option('-k', '--secret-key', required=False, help='Set secret key to enable jwt token authentication.')
@click.option('-l', '--local-package', is_flag=True, help='Enable use of local compute package')
@click.option('-n', '--name', required=False, default="reducer" + str(uuid.uuid4())[:8], help='Set service name')
@click.option('-in', '--init', required=True, default=None,
@click.option('-in', '--init', required=False, default=None,
help='Set to a filename to (re)init reducer state from file.')
@click.pass_context
def dashboard_cmd(ctx, host, port, secret_key, local_package, name, init):
Expand All @@ -177,9 +183,38 @@ def dashboard_cmd(ctx, host, port, secret_key, local_package, name, init):
try:
fedn_config = get_statestore_config_from_file(config['init'])
except Exception as e:
print('Failed to read config from settings file, exiting.', flush=True)
print(e, flush=True)
exit(-1)
print('Failed to read config from settings file, trying default values.', flush=True)
fedn_config = {
"statestore": {
"type": "MongoDB",
"mongo_config": {
"username": "admin",
"password": "admin",
"host": "localhost",
"port": 27017
}
},
"network_id": "fedn-network",
"controller": {
"host": "localhost",
"port": 8092,
"debug": True
},
"storage": {
"storage_type": "S3",
"storage_config": {
"storage_hostname": "localhost",
"storage_port": 9100,
"storage_access_key": "admin",
"storage_secret_key": "password",
"storage_bucket": "fedn-models",
"context_bucket": "fedn-context",
"storage_secure_mode": False
}
}
}
# print(e, flush=True)
# exit(-1)

if not remote:
_ = check_helper_config_file(fedn_config)
Expand Down Expand Up @@ -242,7 +277,7 @@ def dashboard_cmd(ctx, host, port, secret_key, local_package, name, init):
@click.option('-p', '--discoverport', required=False, help='Port for discovery services (reducer).')
@click.option('-t', '--token', required=False, help='Set token provided by reducer if enabled')
@click.option('-n', '--name', required=False, default="combiner" + str(uuid.uuid4())[:8], help='Set name for combiner.')
@click.option('-h', '--host', required=False, default="combiner", help='Set hostname.')
@click.option('-h', '--host', required=False, default="localhost", help='Set hostname.')
@click.option('-i', '--port', required=False, default=12080, help='Set port.')
@click.option('-f', '--fqdn', required=False, default=None, help='Set fully qualified domain name')
@click.option('-s', '--secure', is_flag=True, help='Enable SSL/TLS encrypted gRPC channels.')
Expand All @@ -266,6 +301,13 @@ def combiner_cmd(ctx, discoverhost, discoverport, token, name, host, port, fqdn,
:param max_clients:
:param init:
"""

if not init:
if not discoverhost:
discoverhost = "localhost"
if not discoverport:
discoverport = 8092

config = {'discover_host': discoverhost, 'discover_port': discoverport, 'token': token, 'host': host,
'port': port, 'fqdn': fqdn, 'name': name, 'secure': secure, 'verify': verify, 'max_clients': max_clients,
'init': init, 'aggregator': aggregator}
Expand All @@ -275,3 +317,18 @@ def combiner_cmd(ctx, discoverhost, discoverport, token, name, host, port, fqdn,

combiner = Combiner(config)
combiner.run()


@run_cmd.command('controller')
@click.pass_context
def controller_cmd(ctx):
"""
"""
# config = {'discover_host': discoverhost, 'discover_port': discoverport, 'token': token, 'host': host,
# 'port': port, 'fqdn': fqdn, 'name': name, 'secure': secure, 'verify': verify, 'max_clients': max_clients,
# 'init': init, 'aggregator': aggregator}

# if config['init']:
# apply_config(config)
controller = Controller()
controller.run()
3 changes: 3 additions & 0 deletions fedn/fedn/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import yaml

from fedn.common.log_config import logger

global STATESTORE_CONFIG
global MODELSTORAGE_CONFIG

Expand Down Expand Up @@ -29,6 +31,7 @@ def get_statestore_config(file=None):
if file is None:
get_environment_config()
file = STATESTORE_CONFIG

with open(file, 'r') as config_file:
try:
settings = dict(yaml.safe_load(config_file))
Expand Down
1 change: 0 additions & 1 deletion fedn/fedn/common/storage/db/mongo.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import pymongo


def connect_to_mongodb(config, network_id):
"""
Expand Down
Empty file.
71 changes: 71 additions & 0 deletions fedn/fedn/common/storage/filesystem/filesystem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import os
import uuid

class LocalFileSystemModelRepository:
def __init__(self, directory='./fedn-files'):
self.directory = directory
if not os.path.exists(directory):
os.makedirs(directory)

def get_model_path(self, model_id):
return os.path.join(self.directory, model_id)

def get_model(self, model_id):
model_path = self.get_model_path(model_id)
if os.path.exists(model_path):
with open(model_path, 'rb') as file:
return file.read()
else:
raise FileNotFoundError(f"Model with ID {model_id} not found.")

def get_model_stream(self, model_id):
model_path = self.get_model_path(model_id)
if os.path.exists(model_path):
return open(model_path, 'rb')
else:
raise FileNotFoundError(f"Model with ID {model_id} not found.")

def set_model(self, model, is_file=True):
model_id = str(uuid.uuid4())
model_path = self.get_model_path(model_id)

if is_file:
# If model is a file path, copy the file content.
with open(model, 'rb') as src, open(model_path, 'wb') as dst:
dst.write(src.read())
else:
# If model is a binary content, write it directly.
with open(model_path, 'wb') as file:
file.write(model)

return model_id

# Methods for compute_package can be similarly implemented
def set_compute_package(self, name, compute_package, is_file=True):
package_path = self.get_model_path(name)
if is_file:
print("MMMMMMMMMMMMMMMMMMM")
print(package_path)
print(compute_package)
with open(compute_package, 'rb') as src, open(package_path, 'wb') as dst:
dst.write(src.read())
else:
with open(package_path, 'wb') as file:
file.write(compute_package)

def get_compute_package(self, compute_package):
print("GETTING COMPUTE PACKAGE")
package_path = self.get_model_path(compute_package)
print(package_path)
if os.path.exists(package_path):
with open(package_path, 'rb') as file:
return file.read()
else:
raise FileNotFoundError(f"Compute package {compute_package} not found.")

def delete_compute_package(self, compute_package):
package_path = self.get_model_path(compute_package)
if os.path.exists(package_path):
os.remove(package_path)
else:
raise FileNotFoundError(f"Compute package {compute_package} not found.")
2 changes: 1 addition & 1 deletion fedn/fedn/network/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class APIClient:
:type verify: bool
"""

def __init__(self, host, port, secure=False, verify=False):
def __init__(self, host='localhost', port='8092', secure=False, verify=False):
self.host = host
self.port = port
self.secure = secure
Expand Down
25 changes: 19 additions & 6 deletions fedn/fedn/network/api/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,13 @@ def set_compute_package(self, file, helper_type):
if file and self._allowed_file_extension(file.filename):
filename = secure_filename(file.filename)
# TODO: make configurable, perhaps in config.py or package.py
file_path = os.path.join("/app/client/package/", filename)
file_path = os.path.join(os.getcwd(), filename)
print("ASDASDASDASDASD")
print(file_path)
file.seek(0, 2) # seeks the end of the file
filesize = file.tell() # tell at which byte we are
print(filesize)
file.seek(0)
file.save(file_path)

if (
Expand Down Expand Up @@ -264,12 +270,15 @@ def _get_compute_package_name(self):
message = "No compute package found."
return None, message
else:
print("<><><><><><><>><><><><><")
try:
print(package_objects)
name = package_objects["filename"]
except KeyError as e:
message = "No compute package found. Key error."
print(e)
return None, message
print("SUCCESS <><><<><><><><><><><")
return name, "success"

def get_compute_package(self):
Expand Down Expand Up @@ -309,19 +318,23 @@ def download_compute_package(self, name):
mutex = threading.Lock()
mutex.acquire()
# TODO: make configurable, perhaps in config.py or package.py
print("SENDING >?>?>?>?>>?>?>?>?>?>?>?>?>")
print("{}{}".format(os.getcwd()+"./", name))
return send_from_directory(
"/app/client/package/", name, as_attachment=True
os.getcwd()+"/./", name, as_attachment=True
)
except Exception:
except Exception as err:
print("IN EXCEPTION >?>?>?>?>?>?>?>?>?>")
print(err)
try:
data = self.control.get_compute_package(name)
# TODO: make configurable, perhaps in config.py or package.py
file_path = os.path.join("/app/client/package/", name)
file_path = os.path.join("./", name)
with open(file_path, "wb") as fh:
fh.write(data)
# TODO: make configurable, perhaps in config.py or package.py
return send_from_directory(
"/app/client/package/", name, as_attachment=True
"./", name, as_attachment=True
)
except Exception:
raise
Expand All @@ -342,7 +355,7 @@ def _create_checksum(self, name=None):
if name is None:
return False, message, ""
file_path = os.path.join(
"/app/client/package/", name
".//", name
) # TODO: make configurable, perhaps in config.py or package.py
try:
sum = str(sha(file_path))
Expand Down
Loading

0 comments on commit e180369

Please sign in to comment.