Skip to content

Commit a30911e

Browse files
committed
overwriting timestamp value after _annotate() is finished, fixed some pydantic warnings
1 parent 9dcad01 commit a30911e

File tree

3 files changed

+52
-38
lines changed

3 files changed

+52
-38
lines changed

clams/app/__init__.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def __init__(self):
7777

7878
self.metadata_param_caster = ParameterCaster(self.metadata_param_spec)
7979
self.annotate_param_caster = ParameterCaster(self.annotate_param_spec)
80-
self.logger = logging.getLogger(self.metadata.identifier)
80+
self.logger = logging.getLogger(str(self.metadata.identifier))
8181

8282
def appmetadata(self, **kwargs: List[str]) -> str:
8383
"""
@@ -138,6 +138,7 @@ def annotate(self, mmif: Union[str, dict, Mmif], **runtime_params: List[str]) ->
138138
"""
139139
if not isinstance(mmif, Mmif):
140140
mmif = Mmif(mmif)
141+
existing_view_ids = {view.id for view in mmif.views}
141142
issued_warnings = []
142143
for key in runtime_params:
143144
if key not in self.annotate_param_spec:
@@ -156,7 +157,8 @@ def annotate(self, mmif: Union[str, dict, Mmif], **runtime_params: List[str]) ->
156157
warnings_view = annotated.new_view()
157158
self.sign_view(warnings_view, refined)
158159
warnings_view.metadata.warnings = issued_warnings
159-
td = datetime.now() - t
160+
run_id = datetime.now()
161+
td = run_id - t
160162
runningTime = refined.get('runningTime', False)
161163
hwFetch = refined.get('hwFetch', False)
162164
runtime_recs = {}
@@ -180,7 +182,8 @@ def annotate(self, mmif: Union[str, dict, Mmif], **runtime_params: List[str]) ->
180182
name, mem = gpu.split(', ')
181183
runtime_recs['cuda'].append(self._cuda_device_name_concat(name, mem))
182184
for annotated_view in annotated.views:
183-
if annotated_view.metadata.app == self.metadata.identifier:
185+
if annotated_view.id not in existing_view_ids and annotated_view.metadata.app == str(self.metadata.identifier):
186+
annotated_view.metadata.timestamp = run_id
184187
profiling_data = {}
185188
if runningTime:
186189
profiling_data['runningTime'] = str(td)
@@ -265,7 +268,7 @@ def sign_view(self, view: View, runtime_conf: dict) -> None:
265268
:param view: a view to sign
266269
:param runtime_conf: runtime configuration of the app as k-v pairs
267270
"""
268-
view.metadata.app = self.metadata.identifier
271+
view.metadata.app = str(self.metadata.identifier)
269272
params_map = {p.name: p for p in self.metadata.parameters}
270273
if self._RAW_PARAMS_KEY in runtime_conf:
271274
for k, v in runtime_conf.items():
@@ -300,7 +303,7 @@ def set_error_view(self, mmif: Union[str, dict, Mmif], **runtime_conf: List[str]
300303
mmif = Mmif(mmif)
301304
error_view: Optional[View] = None
302305
for view in reversed(mmif.views):
303-
if view.metadata.app == self.metadata.identifier:
306+
if view.metadata.app == str(self.metadata.identifier):
304307
error_view = view
305308
break
306309
if error_view is None:
@@ -358,7 +361,7 @@ def _get_profile_path(self, param_hash: str) -> pathlib.Path:
358361
:return: Path to the profile file
359362
"""
360363
# Sanitize app identifier for filesystem use
361-
app_id = self.metadata.identifier.replace('/', '-').replace(':', '-')
364+
app_id = str(self.metadata.identifier).replace('/', '-').replace(':', '-')
362365
cache_base = pathlib.Path(os.environ.get('XDG_CACHE_HOME', pathlib.Path.home() / '.cache'))
363366
cache_dir = cache_base / 'clams' / 'memory_profiles' / app_id
364367
return cache_dir / f"memory_{param_hash}.json"

clams/appmetadata/__init__.py

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,6 @@ def validate_properties(cls, value):
131131
def __init__(self, **kwargs):
132132
super().__init__(**kwargs)
133133

134-
@pydantic.field_validator('at_type', mode='after') # because pydantic v2 doesn't auto-convert url to string
135-
@classmethod
136-
def stringify(cls, val):
137-
return str(val)
138-
139134
@pydantic.field_validator('at_type', mode='before')
140135
@classmethod
141136
def at_type_must_be_str(cls, v):
@@ -375,28 +370,26 @@ class AppMetadata(pydantic.BaseModel):
375370
}
376371

377372
@pydantic.model_validator(mode='after')
378-
@classmethod
379-
def assign_versions(cls, data):
380-
if data.app_version == '':
381-
data.app_version = generate_app_version()
382-
if data.mmif_version == '':
383-
data.mmif_version = get_mmif_specver()
384-
return data
373+
def assign_versions(self):
374+
if self.app_version == '':
375+
self.app_version = generate_app_version()
376+
if self.mmif_version == '':
377+
self.mmif_version = get_mmif_specver()
378+
return self
385379

386380
@pydantic.model_validator(mode='after')
387-
@classmethod
388-
def validate_gpu_memory(cls, data):
381+
def validate_gpu_memory(self):
389382
import warnings
390-
if data.est_gpu_mem_typ > 0 and data.est_gpu_mem_min > 0:
391-
if data.est_gpu_mem_typ < data.est_gpu_mem_min:
383+
if self.est_gpu_mem_typ > 0 and self.est_gpu_mem_min > 0:
384+
if self.est_gpu_mem_typ < self.est_gpu_mem_min:
392385
warnings.warn(
393-
f"est_gpu_mem_typ ({data.est_gpu_mem_typ} MB) is less than "
394-
f"est_gpu_mem_min ({data.est_gpu_mem_min} MB). "
395-
f"Setting est_gpu_mem_typ to {data.est_gpu_mem_min} MB.",
386+
f"est_gpu_mem_typ ({self.est_gpu_mem_typ} MB) is less than "
387+
f"est_gpu_mem_min ({self.est_gpu_mem_min} MB). "
388+
f"Setting est_gpu_mem_typ to {self.est_gpu_mem_min} MB.",
396389
UserWarning
397390
)
398-
data.est_gpu_mem_typ = data.est_gpu_mem_min
399-
return data
391+
self.est_gpu_mem_typ = self.est_gpu_mem_min
392+
return self
400393

401394
@pydantic.field_validator('identifier', mode='before')
402395
@classmethod
@@ -405,11 +398,7 @@ def append_version(cls, val):
405398
suffix = generate_app_version()
406399
return '/'.join(map(lambda x: x.strip('/'), filter(None, (prefix, val, suffix))))
407400

408-
@pydantic.field_validator('url', 'identifier', mode='after') # because pydantic v2 doesn't auto-convert url to string
409-
@classmethod
410-
def stringify(cls, val):
411-
return str(val)
412-
401+
413402
def _check_input_duplicate(self, a_input):
414403
for elem in self.input:
415404
if isinstance(elem, list):

tests/test_clamsapp.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,12 @@ def test_sign_view(self):
234234
m = Mmif(self.in_mmif)
235235
v1 = m.new_view()
236236
self.app.sign_view(v1, {})
237-
self.assertEqual(v1.metadata.app, self.app.metadata.identifier)
237+
self.assertEqual(v1.metadata.app, str(self.app.metadata.identifier))
238238
self.assertEqual(len(v1.metadata.parameters), 0)
239239
v2 = m.new_view()
240240
args2 = {'undefined_param1': ['value1']} # values are lists as our restifier uses `to_dict(flat=False)`
241241
self.app.sign_view(v2, self.app._refine_params(**args2))
242-
self.assertEqual(v2.metadata.app, self.app.metadata.identifier)
242+
self.assertEqual(v2.metadata.app, str(self.app.metadata.identifier))
243243
self.assertEqual(len(v2.metadata.parameters), 1)
244244
self.assertFalse(clams.ClamsApp._RAW_PARAMS_KEY in v2.metadata.appConfiguration)
245245
for param in self.app.metadata.parameters:
@@ -271,19 +271,41 @@ def test_annotate(self):
271271
out_mmif = Mmif(out_mmif)
272272
self.assertEqual(len(out_mmif.views), 2)
273273
for v in out_mmif.views:
274-
if v.metadata.app == self.app.metadata.identifier:
274+
if v.metadata.app == str(self.app.metadata.identifier):
275275
self.assertEqual(len(v.metadata.parameters), 0) # no params were passed when `annotate()` was called
276276
out_mmif = self.app.annotate(self.in_mmif, pretty=[str(False)])
277277
out_mmif = Mmif(out_mmif)
278278
for v in out_mmif.views:
279-
if v.metadata.app == self.app.metadata.identifier:
279+
if v.metadata.app == str(self.app.metadata.identifier):
280280
self.assertEqual(len(v.metadata.parameters), 1) # 'pretty` parameter was passed
281281
out_mmif = Mmif(self.app.annotate(out_mmif))
282282
self.assertEqual(len(out_mmif.views), 4)
283283
views = list(out_mmif.views)
284284
# insertion order is kept
285-
self.assertTrue(views[0].metadata.timestamp < views[1].metadata.timestamp)
286-
285+
self.assertEqual(views[0].metadata.timestamp, views[1].metadata.timestamp)
286+
self.assertEqual(views[2].metadata.timestamp, views[3].metadata.timestamp)
287+
self.assertTrue(views[1].metadata.timestamp < views[2].metadata.timestamp)
288+
289+
def test_run_id(self):
290+
# first run
291+
out_mmif = Mmif(self.app.annotate(self.in_mmif))
292+
app_views = [v for v in out_mmif.views if v.metadata.app == str(self.app.metadata.identifier)]
293+
self.assertTrue(len(app_views) > 0)
294+
first_timestamp = app_views[0].metadata.timestamp
295+
for view in app_views[1:]:
296+
self.assertEqual(first_timestamp, view.metadata.timestamp)
297+
# second run
298+
out_mmif2 = Mmif(self.app.annotate(out_mmif))
299+
app_views2 = [v for v in out_mmif2.views if v.metadata.app == str(self.app.metadata.identifier)]
300+
self.assertEqual(len(app_views2), len(app_views) * 2)
301+
second_timestamp = app_views2[-1].metadata.timestamp
302+
self.assertNotEqual(first_timestamp, second_timestamp)
303+
for view in app_views2:
304+
if view.id in [v.id for v in app_views]:
305+
self.assertEqual(first_timestamp, view.metadata.timestamp)
306+
else:
307+
self.assertEqual(second_timestamp, view.metadata.timestamp)
308+
287309
def test_annotate_returns_invalid_mmif(self):
288310
m = Mmif(self.in_mmif)
289311
v = m.new_view()

0 commit comments

Comments
 (0)