Skip to content

Commit 39d4872

Browse files
committed
Merge remote-tracking branch 'mhmdk0/webui-new-design' into webui-new-design
2 parents bb4e3c4 + 13cd7a1 commit 39d4872

File tree

13 files changed

+118
-70
lines changed

13 files changed

+118
-70
lines changed

cli/medperf/commands/association/utils.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,6 @@ def filter_latest_associations(associations, experiment_key, component_key):
5353
return latest_associations
5454

5555

56-
def get_last_component(associations, experiment_key):
57-
associations.sort(key=lambda assoc: parse_datetime(assoc["created_at"]))
58-
experiments_component = {}
59-
for assoc in associations:
60-
experiment_id = assoc[experiment_key]
61-
experiments_component[experiment_id] = assoc
62-
63-
experiments_component = list(experiments_component.values())
64-
return experiments_component
65-
66-
6756
def get_experiment_associations(
6857
experiment_id: int,
6958
experiment_type: str,
@@ -131,10 +120,6 @@ def _post_process_associtations(
131120
):
132121

133122
assocs = filter_latest_associations(associations, experiment_type, component_type)
134-
if component_type == "aggregator":
135-
# an experiment should only have one aggregator
136-
assocs = get_last_component(assocs, experiment_type)
137-
138123
if approval_status:
139124
approval_status = approval_status.upper()
140125
assocs = [

cli/medperf/commands/training/set_aggregator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ def submit(self):
5353
self.approved = self.approved or approval_prompt(msg)
5454

5555
if self.approved:
56-
self.comms.set_training_exp_aggregator(self.training_exp_id, body)
56+
self.comms.update_training_exp(self.training_exp_id, body)
5757
return
5858
raise CleanExit("Aggregator setting cancelled")

cli/medperf/commands/training/submit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def run(cls, training_exp_info: dict):
3030
ui.text = "Getting FL admin Container"
3131
submission.get_fl_admin_mlcube()
3232
ui.print("> Completed retrieving FL Container")
33-
ui.text = "Getting aggregator Container"
33+
ui.text = "Checking if an aggregator is provided"
3434
submission.get_aggregator()
3535
ui.text = "Submitting TrainingExp to MedPerf"
3636
updated_benchmark_body = submission.submit()

cli/medperf/comms/rest.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -880,17 +880,6 @@ def associate_training_dataset(self, data_uid: int, training_exp_id: int):
880880
error_msg = "Could not associate dataset to training_exp"
881881
return self.__post(url, json=data, error_msg=error_msg)
882882

883-
def set_training_exp_aggregator(self, training_exp_id: int, data: dict):
884-
"""Set the aggregator for a training experiment.
885-
886-
Args:
887-
training_exp_id (int): Training experiment UID
888-
aggregator_id (int): Aggregator UID
889-
"""
890-
url = f"{self.server_url}/training/{training_exp_id}/"
891-
error_msg = "Could not set aggregator on training experiment"
892-
return self.__put(url, json=data, error_msg=error_msg)
893-
894883
# updates associations
895884
def update_benchmark_dataset_association(
896885
self, benchmark_uid: int, dataset_uid: int, data: str

cli/medperf/tests/commands/association/test_utils.py

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -133,42 +133,3 @@ def test_3_latest_associations():
133133
assert sorted(result, key=lambda x: (x["component"], x["experiment"])) == sorted(
134134
expected, key=lambda x: (x["component"], x["experiment"])
135135
)
136-
137-
138-
def test_1_last_component():
139-
# Arrange
140-
associations = [
141-
{"created_at": "2025-04-16 17:38:33", "component": 1, "experiment": 2},
142-
{"created_at": "2025-04-16 17:34:33", "component": 1, "experiment": 2},
143-
{"created_at": "2025-04-16 17:32:33", "component": 2, "experiment": 2},
144-
]
145-
expected = [associations[0]]
146-
147-
# Act
148-
result = utils.get_last_component(associations, "experiment")
149-
150-
# Assert
151-
# sort them in some way
152-
assert sorted(result, key=lambda x: (x["component"], x["experiment"])) == sorted(
153-
expected, key=lambda x: (x["component"], x["experiment"])
154-
)
155-
156-
157-
def test_2_last_component():
158-
# Arrange
159-
associations = [
160-
{"created_at": "2025-04-16 17:38:33", "component": 1, "experiment": 2},
161-
{"created_at": "2025-04-16 17:34:33", "component": 1, "experiment": 2},
162-
{"created_at": "2025-04-17 17:32:33", "component": 2, "experiment": 2},
163-
{"created_at": "2025-04-16 17:32:33", "component": 2, "experiment": 3},
164-
]
165-
expected = [associations[2], associations[3]]
166-
167-
# Act
168-
result = utils.get_last_component(associations, "experiment")
169-
170-
# Assert
171-
# sort them in some way
172-
assert sorted(result, key=lambda x: (x["component"], x["experiment"])) == sorted(
173-
expected, key=lambda x: (x["component"], x["experiment"])
174-
)

server/aggregator/views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from .models import Aggregator
77
from .serializers import AggregatorSerializer
8-
from training.serializers import WriteTrainingExperimentSerializer
8+
from training.serializers import ReadTrainingExperimentSerializer
99
from drf_spectacular.utils import extend_schema
1010

1111

@@ -35,7 +35,7 @@ def post(self, request, format=None):
3535

3636

3737
class AggregatorTrainingExperimentList(GenericAPIView):
38-
serializer_class = WriteTrainingExperimentSerializer
38+
serializer_class = ReadTrainingExperimentSerializer
3939
queryset = ""
4040

4141
def get_object(self, pk):
@@ -52,7 +52,7 @@ def get(self, request, pk, format=None):
5252
aggregator = self.get_object(pk)
5353
training_exps = aggregator.training_experiments.all()
5454
training_exps = self.paginate_queryset(training_exps)
55-
serializer = WriteTrainingExperimentSerializer(training_exps, many=True)
55+
serializer = ReadTrainingExperimentSerializer(training_exps, many=True)
5656
return self.get_paginated_response(serializer.data)
5757

5858

server/aggregator_association/__init__.py

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class AggregatorAssociationConfig(AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
6+
name = 'aggregator_association'
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Generated by Django 4.2.11 on 2024-04-29 13:21
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
initial = True
11+
12+
dependencies = [
13+
("aggregator", "0001_initial"),
14+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
15+
]
16+
17+
operations = [
18+
migrations.CreateModel(
19+
name="ExperimentAggregator",
20+
fields=[
21+
(
22+
"id",
23+
models.BigAutoField(
24+
auto_created=True,
25+
primary_key=True,
26+
serialize=False,
27+
verbose_name="ID",
28+
),
29+
),
30+
("metadata", models.JSONField(default=dict)),
31+
(
32+
"approval_status",
33+
models.CharField(
34+
choices=[
35+
("PENDING", "PENDING"),
36+
("APPROVED", "APPROVED"),
37+
("REJECTED", "REJECTED"),
38+
],
39+
default="PENDING",
40+
max_length=100,
41+
),
42+
),
43+
("approved_at", models.DateTimeField(blank=True, null=True)),
44+
("created_at", models.DateTimeField(auto_now_add=True)),
45+
("modified_at", models.DateTimeField(auto_now=True)),
46+
(
47+
"aggregator",
48+
models.ForeignKey(
49+
on_delete=django.db.models.deletion.PROTECT,
50+
to="aggregator.aggregator",
51+
),
52+
),
53+
(
54+
"initiated_by",
55+
models.ForeignKey(
56+
on_delete=django.db.models.deletion.PROTECT,
57+
to=settings.AUTH_USER_MODEL,
58+
),
59+
),
60+
],
61+
options={
62+
"ordering": ["created_at"],
63+
},
64+
),
65+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Generated by Django 4.2.11 on 2024-04-29 13:21
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
initial = True
10+
11+
dependencies = [
12+
("training", "0001_initial"),
13+
("aggregator_association", "0001_initial"),
14+
]
15+
16+
operations = [
17+
migrations.AddField(
18+
model_name="experimentaggregator",
19+
name="training_exp",
20+
field=models.ForeignKey(
21+
on_delete=django.db.models.deletion.CASCADE,
22+
to="training.trainingexperiment",
23+
),
24+
),
25+
]

0 commit comments

Comments
 (0)