Skip to content

Commit

Permalink
Update study def and study manager to fit study cli and all required …
Browse files Browse the repository at this point in the history
…arguments (NVIDIA#480)
  • Loading branch information
IsaacYangSLA authored May 4, 2022
1 parent 6cfcd15 commit b021756
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 23 deletions.
32 changes: 16 additions & 16 deletions nvflare/apis/impl/study_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import json
import logging
import time
from datetime import date, datetime
from typing import List, Optional, Tuple

Expand Down Expand Up @@ -61,7 +62,7 @@ def add_study(self, study: Study, fl_ctx: FLContext) -> Tuple[Optional[Study], s
- The name of the study must be unique;
- participating_clients and participating_admins must be defined;
- Start and end date must make sense.
- Start and end time must make sense.
Args:
study: the caller-provided study info
Expand All @@ -71,6 +72,8 @@ def add_study(self, study: Study, fl_ctx: FLContext) -> Tuple[Optional[Study], s
updated study info (e.g. created_at is set) and an emtpy string if successful
None and an error message if the provided study is not valid
"""
if not isinstance(study, Study):
return None, f"Expect Study object, received {study.__class__.__name__}"
if study.name in self._existing_studies:
return None, "Unable to add duplicated study name."
if not study.participating_clients:
Expand All @@ -79,21 +82,21 @@ def add_study(self, study: Study, fl_ctx: FLContext) -> Tuple[Optional[Study], s
return None, "Study has no contact info."
if not study.participating_admins:
return None, "Study has no participating admins."
if not study.start_date:
return None, "Study has no start date."
if not study.end_date:
return None, "Study has no end date."
if study.end_date < study.start_date:
if not study.start_time:
return None, "Study has no start time."
if not study.end_time:
return None, "Study has no end time."
if study.end_time < study.start_time:
return (
None,
f"Expect end_date later than start_date. Got start_date={study.start_date} and end_data={study.end_date}",
f"Expect end_time later than start_time. Got start_time={study.start_time} and end_time={study.end_time}",
)
study.created_at = datetime.utcnow()
study.created_at = time.time()
serialized_study = self._study_to_bytes(study)
try:
store = self._get_store(fl_ctx)
except BaseException as e:
return None, e.message
return None, str(e)
try:
self._existing_studies = json.loads(store.get_data(StudyManager.STORAGE_KEY).decode("utf-8"))
except BaseException:
Expand All @@ -102,7 +105,7 @@ def add_study(self, study: Study, fl_ctx: FLContext) -> Tuple[Optional[Study], s
store.create_object(
uri=study.name,
data=serialized_study,
meta={"start_date": study.start_date, "end_date": study.end_date},
meta={"start_time": study.start_time, "end_time": study.end_time},
overwrite_existing=True,
)
store.create_object(
Expand All @@ -121,9 +124,6 @@ def add_study(self, study: Study, fl_ctx: FLContext) -> Tuple[Optional[Study], s
def _study_from_bytes(bytes_study):
try:
deserialized_study = json.loads(bytes_study.decode("utf-8"))
deserialized_study["start_date"] = date.fromisoformat(deserialized_study.pop("start_date"))
deserialized_study["end_date"] = date.fromisoformat(deserialized_study.pop("end_date"))
deserialized_study["created_at"] = datetime.fromisoformat(deserialized_study.pop("created_at"))
return Study(**deserialized_study)
except BaseException:
return None
Expand Down Expand Up @@ -164,7 +164,7 @@ def list_active_studies(self, fl_ctx: FLContext) -> List[str]:
Returns:
A list of study names
"""
today = date.today()
current_time = time.time()
active_studies = list()
try:
store = self._get_store(fl_ctx)
Expand All @@ -173,9 +173,9 @@ def list_active_studies(self, fl_ctx: FLContext) -> List[str]:
for st in self.list_studies(fl_ctx):
try:
meta = store.get_meta(st)
if meta["start_date"] > today:
if meta["start_time"] > current_time:
continue
if meta["end_date"] <= today:
if meta["end_time"] <= current_time:
continue
active_studies.append(st)
except BaseException as e:
Expand Down
11 changes: 5 additions & 6 deletions nvflare/apis/study_manager_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.

from abc import ABC, abstractmethod
from datetime import date, datetime
from typing import List, Optional, Tuple

from .fl_context import FLContext
Expand All @@ -30,18 +29,18 @@ def __init__(
contact: str,
participating_clients: List[str],
participating_admins: List[str],
start_date: date,
end_date: date,
start_time: float,
end_time: float,
reviewers=None,
created_at: datetime = None,
created_at: float = None,
):
self.name = name
self.description = description
self.contact = contact
self.participating_clients = participating_clients
self.participating_admins = participating_admins
self.start_date = start_date
self.end_date = end_date
self.start_time = start_time
self.end_time = end_time
self.reviewers = reviewers
self.created_at = created_at

Expand Down
2 changes: 1 addition & 1 deletion nvflare/lighter/study.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def get_datetime_input(prompt):
answer = input(prompt)
try:
datetime_result = datetime.strptime(answer, "%m/%d/%Y %H:%M:%S")
result = int(time.mktime(datetime_result.timetuple()))
result = time.mktime(datetime_result.timetuple())
break
except:
print(f"Expect MM/DD/YYYY hh:mm:ss, but got {answer}")
Expand Down

0 comments on commit b021756

Please sign in to comment.