Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/SK-1096 | Add set helper to v1 api #723

Merged
merged 2 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion fedn/network/api/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from fedn.network.api.v1.client_routes import bp as client_bp
from fedn.network.api.v1.combiner_routes import bp as combiner_bp
from fedn.network.api.v1.helper_routes import bp as helper_bp
from fedn.network.api.v1.inference_routes import bp as inference_bp
from fedn.network.api.v1.model_routes import bp as model_bp
from fedn.network.api.v1.package_routes import bp as package_bp
Expand All @@ -8,4 +9,4 @@
from fedn.network.api.v1.status_routes import bp as status_bp
from fedn.network.api.v1.validation_routes import bp as validation_bp

_routes = [client_bp, combiner_bp, model_bp, package_bp, round_bp, session_bp, status_bp, validation_bp, inference_bp]
_routes = [client_bp, combiner_bp, model_bp, package_bp, round_bp, session_bp, status_bp, validation_bp, inference_bp, helper_bp]
62 changes: 62 additions & 0 deletions fedn/network/api/v1/helper_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from flask import Blueprint, jsonify, request

from fedn.network.api.auth import jwt_auth_required
from fedn.network.api.v1.shared import api_version, package_store
from fedn.network.storage.statestore.stores.shared import EntityNotFound

bp = Blueprint("helper", __name__, url_prefix=f"/api/{api_version}/helpers")



@bp.route("/active", methods=["GET"])
@jwt_auth_required(role="admin")
def get_active_helper():
"""Get active helper
Retrieves the active helper
---
tags:
- Helpers
responses:
200:
description: Active helper
404:
description: No active helper
500:
description: An unexpected error occurred
"""
try:

active_package = package_store.get_active()

response = active_package["helper"]

return jsonify(response), 200
except EntityNotFound:
return jsonify({"message": "No active helper"}), 404
except Exception:
return jsonify({"message": "An unexpected error occurred"}), 500

@bp.route("/active", methods=["PUT"])
@jwt_auth_required(role="admin")
def set_active_helper():
"""Set active helper
Sets the active helper
---
tags:
- Helpers
responses:
200:
description: Active helper set
500:
description: An unexpected error occurred
"""
try:
data = request.get_json()
helper = data["helper"]
package_store.set_active_helper(helper)

return jsonify({"message": "Active helper set"}), 200
except ValueError:
return jsonify({"message": "Helper is required to be either 'numpyhelper', 'binaryhelper' or 'androidhelper'"}), 400
except Exception:
return jsonify({"message": "An unexpected error occurred"}), 500
6 changes: 3 additions & 3 deletions fedn/network/api/v1/package_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

from fedn.common.config import FEDN_COMPUTE_PACKAGE_DIR
from fedn.network.api.auth import jwt_auth_required
from fedn.network.api.v1.shared import api_version, get_post_data_to_kwargs, get_typed_list_headers, get_use_typing, mdb, repository
from fedn.network.storage.statestore.stores.package_store import PackageStore
from fedn.network.api.v1.shared import (api_version, get_post_data_to_kwargs,
get_typed_list_headers, get_use_typing,
package_store, repository)
from fedn.network.storage.statestore.stores.shared import EntityNotFound

bp = Blueprint("package", __name__, url_prefix=f"/api/{api_version}/packages")

package_store = PackageStore(mdb, "control.package")


@bp.route("/", methods=["GET"])
Expand Down
5 changes: 4 additions & 1 deletion fedn/network/api/v1/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
import pymongo
from pymongo.database import Database

from fedn.network.api.shared import modelstorage_config, network_id, statestore_config
from fedn.network.api.shared import (modelstorage_config, network_id,
statestore_config)
from fedn.network.storage.s3.base import RepositoryBase
from fedn.network.storage.s3.miniorepository import MINIORepository
from fedn.network.storage.s3.repository import Repository
from fedn.network.storage.statestore.stores.client_store import ClientStore
from fedn.network.storage.statestore.stores.package_store import PackageStore

api_version = "v1"
mc = pymongo.MongoClient(**statestore_config["mongo_config"])
mc.server_info()
mdb: Database = mc[network_id]

client_store = ClientStore(mdb, "network.clients")
package_store = PackageStore(mdb, "control.package")

minio_repository: RepositoryBase = None

Expand Down
14 changes: 14 additions & 0 deletions fedn/network/storage/statestore/stores/package_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ def get_active(self, use_typing: bool = False) -> Package:

return Package.from_dict(response, response) if use_typing else from_document(response)

def set_active_helper(self, helper: str) -> bool:
"""Set the active helper
param helper: The helper to set as active
type: str
return: Whether the operation was successful
"""
if not helper or helper == "" or helper not in ["numpyhelper", "binaryhelper", "androidhelper"]:
raise ValueError()

try:
self.database[self.collection].update_one({"key": "active"}, {"$set": {"helper": helper}}, upsert=True)
except Exception:
return False

def _allowed_file_extension(self, filename: str, ALLOWED_EXTENSIONS={"gz", "bz2", "tar", "zip", "tgz"}) -> bool:
"""Check if file extension is allowed.

Expand Down
12 changes: 4 additions & 8 deletions fedn/network/storage/statestore/stores/session_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def from_dict(data: dict) -> "Session":
id=str(data["_id"]),
session_id=data["session_id"] if "session_id" in data else None,
status=data["status"] if "status" in data else None,
session_config=data["session_config"] if "session_config" in data else None
session_config=data["session_config"] if "session_config" in data else None,
)


Expand Down Expand Up @@ -71,7 +71,7 @@ def _validate_session_config(self, session_config: dict) -> Tuple[bool, str]:
if not isinstance(session_config["validate"], bool):
return False, "session_config.validate must be a boolean"

if "helper_type" not in session_config:
if "helper_type" not in session_config or session_config["helper_type"] == "":
return False, "session_config.helper_type is required"

if not isinstance(session_config["helper_type"], str):
Expand All @@ -92,7 +92,7 @@ def _validate(self, item: Session) -> Tuple[bool, str]:
else:
return False, "session_config must be a dict"

return self._validate_session_config(session_config)
return self._validate_session_config(session_config)

def _complement(self, item: Session):
item["status"] = "Created"
Expand All @@ -101,7 +101,6 @@ def _complement(self, item: Session):
if "session_id" not in item or item["session_id"] == "" or not isinstance(item["session_id"], str):
item["session_id"] = str(uuid.uuid4())


def get(self, id: str, use_typing: bool = False) -> Session:
"""Get an entity by id
param id: The id of the entity
Expand Down Expand Up @@ -173,7 +172,4 @@ def list(self, limit: int, skip: int, sort_key: str, sort_order=pymongo.DESCENDI

result = [Session.from_dict(item) for item in response["result"]] if use_typing else response["result"]

return {
"count": response["count"],
"result": result
}
return {"count": response["count"], "result": result}
Loading