Skip to content

Commit 62a24c6

Browse files
committed
update webui
1 parent dbc4221 commit 62a24c6

31 files changed

+634
-1735
lines changed

cli/medperf/commands/asset/submit.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import logging
33

4+
from medperf.commands.model.submit_util import ContinueAssetSubmission
45
from medperf.comms.entity_resources import resources
56
import medperf.config as config
67
from medperf.entities.asset import Asset
@@ -28,6 +29,9 @@ def run(
2829
asset_path (str): Local path to the asset file.
2930
asset_url (str): URL to download the asset from.
3031
operational (bool): Whether to submit as OPERATIONAL state.
32+
33+
Returns:
34+
str: The ID of submitted asset.
3135
"""
3236
ui = config.ui
3337
submission = cls(name, asset_path, asset_url, operational)
@@ -38,10 +42,15 @@ def run(
3842
submission.prepare_asset()
3943
submission.create_asset_object()
4044
submission.validate_asset_file()
41-
ui.text = "Submitting asset to MedPerf"
42-
updated_body = submission.upload()
43-
submission.to_permanent_path(updated_body)
44-
submission.write(updated_body)
45+
46+
if submission.asset.is_model():
47+
return ContinueAssetSubmission.run(submission)
48+
49+
with ui.interactive():
50+
ui.text = "Submitting Asset to MedPerf"
51+
updated_asset_dict = submission.upload()
52+
submission.to_permanent_path(updated_asset_dict)
53+
submission.write(updated_asset_dict)
4554

4655
ui.print(f"Asset registered with UID: {submission.asset.id}")
4756
return submission.asset.id
@@ -103,6 +112,7 @@ def validate_asset_file(self):
103112
self.asset.prepare_asset_files()
104113

105114
def upload(self):
115+
# Note: this is not used for now
106116
updated_body = self.asset.upload()
107117
return updated_body
108118

cli/medperf/commands/mlcube/submit.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from medperf.entities.cube import Cube
55
from medperf.exceptions import InvalidArgumentError
66
from medperf.utils import remove_path, sanitize_path, store_decryption_key
7+
from medperf.commands.model.submit_util import ContinueCubeSubmission
78
import logging
89

910
import yaml
@@ -22,19 +23,26 @@ def run(
2223
2324
Args:
2425
submit_info (dict): Dictionary containing the cube information.
26+
27+
Returns:
28+
str: The ID of the submitted cube
2529
"""
2630
ui = config.ui
2731
submission = cls(
2832
submit_info, container_config, parameters_config, decryption_key
2933
)
3034
submission.read_config_files()
3135
submission.create_cube_object()
32-
submission.raise_if_model()
3336

3437
with ui.interactive():
3538
ui.text = "Validating Container can be downloaded"
3639
submission.validate()
3740
submission.download_run_files()
41+
42+
if submission.cube.is_model():
43+
return ContinueCubeSubmission.run(submission)
44+
45+
with ui.interactive():
3846
ui.text = "Submitting Container to MedPerf"
3947
updated_cube_dict = submission.upload()
4048
submission.to_permanent_path(updated_cube_dict)
@@ -104,13 +112,6 @@ def create_cube_object(self):
104112
config.tmp_paths.append(self.cube.path)
105113
os.makedirs(self.cube.path, exist_ok=True)
106114

107-
def raise_if_model(self):
108-
if self.cube.is_model():
109-
raise InvalidArgumentError(
110-
"The provided container config file seems to be for a model, not a cube. "
111-
"Please use the 'model submit' command for model submissions."
112-
)
113-
114115
def validate(self):
115116
if self.cube.is_encrypted() and not self.decryption_key:
116117
raise InvalidArgumentError(
Lines changed: 10 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
1-
import os
2-
3-
from git import Optional
4-
5-
import medperf.config as config
6-
from medperf.entities.model import Model
1+
from typing import Optional
72
from medperf.exceptions import InvalidArgumentError
8-
from medperf.utils import remove_path
9-
from medperf.enums import ModelType
103
from medperf.commands.mlcube.submit import SubmitCube
114
from medperf.commands.asset.submit import SubmitAsset
125

@@ -42,7 +35,6 @@ def run(
4235
asset_url (Optional[str]): URL to download the asset from (for ASSET type).
4336
operational (bool): Whether to submit as OPERATIONAL state.
4437
"""
45-
ui = config.ui
4638
submission = cls(
4739
name,
4840
operational,
@@ -56,24 +48,9 @@ def run(
5648
asset_url,
5749
)
5850
submission.validate_inputs()
59-
60-
with ui.interactive():
61-
ui.text = "Submitting model to MedPerf"
62-
if submission.model_type == ModelType.CONTAINER.value:
63-
submission.prepare_container_submission()
64-
submission.create_model_object()
65-
updated_model_body, updated_container_body = submission.upload()
66-
submission.finalize_container_submission(updated_container_body)
67-
else:
68-
submission.prepare_asset_submission()
69-
submission.create_model_object()
70-
updated_model_body, updated_asset_body = submission.upload()
71-
submission.finalize_asset_submission(updated_asset_body)
72-
submission.to_permanent_path(updated_model_body)
73-
submission.write(updated_model_body)
74-
75-
ui.print(f"Model registered with UID: {submission.model.id}")
76-
return submission.model.id
51+
if submission.is_container:
52+
return submission.run_container_submission()
53+
return submission.run_asset_submission()
7754

7855
def __init__(
7956
self,
@@ -98,9 +75,7 @@ def __init__(
9875
self.asset_path = asset_path
9976
self.asset_url = asset_url
10077
self.operational = operational
101-
self.model = None
102-
self.model_type = None
103-
self.subentity_submission = None
78+
self.is_container: bool = None
10479

10580
def validate_inputs(self):
10681
container_provided = (
@@ -124,90 +99,24 @@ def validate_inputs(self):
12499
raise InvalidArgumentError(
125100
"Container config file is required for container-backed model."
126101
)
127-
self.model_type = (
128-
ModelType.CONTAINER.value if container_provided else ModelType.ASSET.value
129-
)
102+
self.is_container = container_provided
130103

131-
def prepare_container_submission(self):
104+
def run_container_submission(self):
132105
submit_info = {
133106
"name": self.name,
134107
"image_hash": self.image_hash,
135108
"additional_files_tarball_url": self.additional_file,
136109
"additional_files_tarball_hash": self.additional_hash,
137110
"state": "OPERATION" if self.operational else "DEVELOPMENT",
138111
}
139-
ui = config.ui
140-
submission = SubmitCube(
112+
return SubmitCube.run(
141113
submit_info,
142114
self.container_config_file,
143115
self.parameters_config_file,
144116
self.decryption_key,
145117
)
146-
submission.read_config_files()
147-
submission.create_cube_object()
148118

149-
ui.text = "Validating Container can be downloaded"
150-
submission.validate()
151-
submission.download_run_files()
152-
self.subentity_submission = submission
153-
154-
def prepare_asset_submission(self):
155-
ui = config.ui
156-
submission = SubmitAsset(
119+
def run_asset_submission(self):
120+
return SubmitAsset.run(
157121
self.name, self.asset_path, self.asset_url, self.operational
158122
)
159-
submission.validate_inputs()
160-
161-
ui.text = "Preparing asset"
162-
submission.prepare_asset()
163-
submission.create_asset_object()
164-
submission.validate_asset_file()
165-
self.subentity_submission = submission
166-
167-
def create_model_object(self):
168-
state = "OPERATION" if self.operational else "DEVELOPMENT"
169-
container = None
170-
asset = None
171-
if self.model_type == ModelType.CONTAINER.value:
172-
container = self.subentity_submission.cube
173-
else:
174-
asset = self.subentity_submission.asset
175-
176-
self.model = Model(
177-
name=self.name,
178-
type=self.model_type,
179-
container=container,
180-
asset=asset,
181-
state=state,
182-
)
183-
config.tmp_paths.append(self.model.path)
184-
os.makedirs(self.model.path, exist_ok=True)
185-
186-
def upload(self):
187-
updated_body = self.model.upload()
188-
subentity_body = (
189-
updated_body["container"]
190-
if self.model_type == ModelType.CONTAINER.value
191-
else updated_body["asset"]
192-
)
193-
return updated_body, subentity_body
194-
195-
def finalize_container_submission(self, updated_body: dict):
196-
self.subentity_submission.to_permanent_path(updated_body)
197-
self.subentity_submission.write(updated_body)
198-
self.subentity_submission.store_decryption_key()
199-
200-
def finalize_asset_submission(self, updated_body: dict):
201-
self.subentity_submission.to_permanent_path(updated_body)
202-
self.subentity_submission.write(updated_body)
203-
204-
def to_permanent_path(self, model_dict):
205-
old_path = self.model.path
206-
updated_model = Model(**model_dict)
207-
new_path = updated_model.path
208-
remove_path(new_path)
209-
os.rename(old_path, new_path)
210-
211-
def write(self, updated_body):
212-
self.model = Model(**updated_body)
213-
self.model.write()
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import os
2+
from typing import TYPE_CHECKING
3+
4+
import medperf.config as config
5+
from medperf.entities.model import Model
6+
from medperf.utils import remove_path
7+
from medperf.enums import ModelType
8+
9+
if TYPE_CHECKING:
10+
from medperf.commands.mlcube.submit import SubmitCube
11+
from medperf.commands.asset.submit import SubmitAsset
12+
13+
14+
class ContinueCubeSubmission:
15+
@classmethod
16+
def run(cls, container_submission: SubmitCube):
17+
"""Finalizes the container submission.
18+
19+
Args:
20+
container_submission (SubmitCube): The submission object for the cube.
21+
"""
22+
submission = cls(container_submission)
23+
submission.create_model_object()
24+
updated_body, container_body = submission.upload()
25+
submission.finalize_container_submission(container_body)
26+
submission.to_permanent_path(updated_body)
27+
submission.write(updated_body)
28+
return submission.model.container.id
29+
30+
def __init__(self, container_submission: SubmitCube):
31+
self.container_submission = container_submission
32+
self.model = None
33+
34+
def create_model_object(self):
35+
self.model = Model(
36+
name=self.container_submission.cube.name,
37+
type=ModelType.CONTAINER.value,
38+
container=self.container_submission.cube,
39+
state=self.container_submission.cube.state,
40+
)
41+
config.tmp_paths.append(self.model.path)
42+
os.makedirs(self.model.path, exist_ok=True)
43+
44+
def upload(self):
45+
updated_body = self.model.upload()
46+
return updated_body, updated_body["container"]
47+
48+
def finalize_container_submission(self, updated_body: dict):
49+
self.container_submission.to_permanent_path(updated_body)
50+
self.container_submission.write(updated_body)
51+
self.container_submission.store_decryption_key()
52+
53+
def to_permanent_path(self, model_dict):
54+
old_path = self.model.path
55+
updated_model = Model(**model_dict)
56+
new_path = updated_model.path
57+
remove_path(new_path)
58+
os.rename(old_path, new_path)
59+
60+
def write(self, updated_body):
61+
self.model = Model(**updated_body)
62+
self.model.write()
63+
64+
65+
class ContinueAssetSubmission:
66+
@classmethod
67+
def run(cls, asset_submission: SubmitAsset):
68+
"""Finalizes the asset submission.
69+
70+
Args:
71+
asset_submission (SubmitAsset): The submission object for the asset.
72+
"""
73+
submission = cls(asset_submission)
74+
submission.create_model_object()
75+
updated_body, asset_body = submission.upload()
76+
submission.finalize_asset_submission(asset_body)
77+
submission.to_permanent_path(updated_body)
78+
submission.write(updated_body)
79+
return submission.model.asset.id
80+
81+
def __init__(self, asset_submission: SubmitAsset):
82+
self.asset_submission = asset_submission
83+
self.model = None
84+
85+
def create_model_object(self):
86+
self.model = Model(
87+
name=self.asset_submission.asset.name,
88+
type=ModelType.ASSET.value,
89+
asset=self.asset_submission.asset,
90+
state=self.asset_submission.asset.state,
91+
)
92+
config.tmp_paths.append(self.model.path)
93+
os.makedirs(self.model.path, exist_ok=True)
94+
95+
def upload(self):
96+
updated_body = self.model.upload()
97+
return updated_body, updated_body["asset"]
98+
99+
def finalize_asset_submission(self, updated_body: dict):
100+
self.asset_submission.to_permanent_path(updated_body)
101+
self.asset_submission.write(updated_body)
102+
103+
def to_permanent_path(self, model_dict):
104+
old_path = self.model.path
105+
updated_model = Model(**model_dict)
106+
new_path = updated_model.path
107+
remove_path(new_path)
108+
os.rename(old_path, new_path)
109+
110+
def write(self, updated_body):
111+
self.model = Model(**updated_body)
112+
self.model.write()

cli/medperf/comms/rest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,19 @@ def get_container_model(self, container_id: int) -> dict:
360360
error_msg = f"Could not retrieve model for container {container_id}"
361361
return self.__get(url, error_msg)
362362

363+
def get_asset_model(self, asset_id: int) -> dict:
364+
"""Retrieves the model for the given asset ID
365+
366+
Args:
367+
asset_id (int): Asset ID
368+
369+
Returns:
370+
dict: Model metadata
371+
"""
372+
url = f"{self.server_url}/assets/{asset_id}/model/"
373+
error_msg = f"Could not retrieve model for asset {asset_id}"
374+
return self.__get(url, error_msg)
375+
363376
# get list
364377
def get_benchmarks(self, filters=dict()) -> List[dict]:
365378
"""Retrieves all benchmarks in the platform.

cli/medperf/entities/asset.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ def __init__(self, *args, **kwargs):
5252
def local_id(self):
5353
return self.name
5454

55+
def is_local(self) -> bool:
56+
return self.asset_url == "local"
57+
58+
def is_model(self) -> bool:
59+
return True
60+
5561
@staticmethod
5662
def remote_prefilter(filters: dict) -> callable:
5763
comms_fn = config.comms.get_assets

0 commit comments

Comments
 (0)