From 3d6bbae013d54538b49ab454500f24aadabda3fb Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 4 Dec 2023 14:52:50 +0100 Subject: [PATCH] list compute packages added --- fedn/fedn/network/api/client.py | 9 ++++ fedn/fedn/network/api/interface.py | 43 +++++++++++++++++++ fedn/fedn/network/api/server.py | 16 +++++++ .../network/statestore/mongostatestore.py | 40 ++++++++++++++++- 4 files changed, 107 insertions(+), 1 deletion(-) diff --git a/fedn/fedn/network/api/client.py b/fedn/fedn/network/api/client.py index 58fc27304..b6ffab2fc 100644 --- a/fedn/fedn/network/api/client.py +++ b/fedn/fedn/network/api/client.py @@ -192,6 +192,15 @@ def get_package(self): response = requests.get(self._get_url('get_package'), verify=self.verify) return response.json() + def list_compute_packages(self): + """ Get all compute packages from the statestore. + + :return: All compute packages with info. + :rtype: dict + """ + response = requests.get(self._get_url('list_compute_packages'), verify=self.verify) + return response.json() + def download_package(self, path): """ Download the compute package. diff --git a/fedn/fedn/network/api/interface.py b/fedn/fedn/network/api/interface.py index 85a839fc1..95b29d48f 100644 --- a/fedn/fedn/network/api/interface.py +++ b/fedn/fedn/network/api/interface.py @@ -320,6 +320,49 @@ def get_compute_package(self): payload[id] = info return jsonify(payload) + def list_compute_packages(self, limit: str = None, skip: str = None): + """Get paginated list of compute packages from the statestore. + + :return: All compute packages as a json response. + :rtype: :class:`flask.Response` + """ + + if limit is None: + return ( + jsonify( + { + "success": False, + "message": "No limit provided.", + } + ), + 404, + ) + + if limit is not None and skip is not None: + limit = int(limit) + skip = int(skip) + + result = self.statestore.list_compute_packages(limit, skip) + if result is None: + return ( + jsonify( + {"success": False, "message": "No compute packages found."} + ), + 404, + ) + arr = [] + for element in result["result"]: + obj = { + "file_name": element["file_name"], + "helper": element["helper"], + "committed_at": element["committed_at"], + "storage_file_name": element["storage_file_name"], + } + arr.append(obj) + + result = {"result": arr, "count": result["count"]} + return jsonify(result) + def download_compute_package(self, name): """Download the compute package. diff --git a/fedn/fedn/network/api/server.py b/fedn/fedn/network/api/server.py index cfb91bece..9199d8921 100644 --- a/fedn/fedn/network/api/server.py +++ b/fedn/fedn/network/api/server.py @@ -218,6 +218,22 @@ def get_package(): return api.get_compute_package() +@app.route("/list_compute_packages", methods=["GET"]) +def list_compute_packages(): + """Get the compute package from the statestore. + return: The compute package as a json object. + rtype: json + """ + + limit = request.args.get("limit", None) + skip = request.args.get("skip", None) + + return api.list_compute_packages( + limit=limit, + skip=skip, + ) + + @app.route("/download_package", methods=["GET"]) def download_package(): """Download the compute package. diff --git a/fedn/fedn/network/statestore/mongostatestore.py b/fedn/fedn/network/statestore/mongostatestore.py index 39fe880e6..02c16ca76 100644 --- a/fedn/fedn/network/statestore/mongostatestore.py +++ b/fedn/fedn/network/statestore/mongostatestore.py @@ -282,7 +282,7 @@ def set_compute_package(self, file_name: str, storage_file_name: str, helper_typ "file_name": file_name, "storage_file_name": storage_file_name, "helper": helper_type, - "committed_at": str(datetime.now()), + "committed_at": datetime.now(), } self.control.package.update_one( @@ -316,6 +316,44 @@ def get_compute_package(self): except (KeyError, IndexError): return None + def list_compute_packages(self, limit: int = None, skip: int = None, sort_key="committed_at", sort_order=pymongo.DESCENDING): + """List compute packages in the statestore (paginated). + + :param limit: The maximum number of compute packages to return. + :type limit: int + :param skip: The number of compute packages to skip. + :type skip: int + :param sort_key: The key to sort by. + :type sort_key: str + :param sort_order: The sort order. + :type sort_order: pymongo.ASCENDING or pymongo.DESCENDING + :return: Dictionary of compute packages in result and count. + :rtype: dict + """ + + result = None + count = None + + find_option = {"key": "package_trail"} + projection = {"_id": False, "key": False} + + try: + if limit is not None and skip is not None: + result = self.control.package.find(find_option, projection).limit(limit).skip(skip).sort(sort_key, sort_order) + else: + result = self.control.package.find(find_option, projection).sort(sort_key, sort_order) + + count = self.control.package.count_documents(find_option) + + except Exception as e: + print("ERROR: {}".format(e), flush=True) + return None + + return { + "result": result, + "count": count, + } + def set_helper(self, helper): """Set the active helper package in statestore.