Coverage for src/backoffice/_config/id_parts.py: 0%

45 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-11-12 10:26 +0000

1"""describes a file holding all parts to create resource ids""" 

2 

3from typing import Mapping, Sequence 

4 

5from pydantic import field_validator 

6 

7from .common import ConfigNode 

8 

9 

10class IdPartsEntry(ConfigNode, frozen=True): 

11 """parts to create resource ids for a specific resource type""" 

12 

13 nouns: Mapping[str, str] 

14 adjectives: Sequence[str] 

15 

16 @field_validator("adjectives", mode="after") 

17 def _sort_adjectives(cls, value: Sequence[str]): 

18 value = list(value) 

19 value.sort( 

20 key=len, reverse=True 

21 ) # such that longest adjective matches first during validation, e.g. 'easy-' vs 'easy-going-' 

22 return value 

23 

24 def get_noun(self, resource_id: str): 

25 if not isinstance(resource_id, str): 

26 raise TypeError(f"invalid resource_id type: {type(resource_id)}") 

27 if not resource_id: 

28 raise ValueError("empty resource_id") 

29 

30 for adj in self.adjectives: 

31 if resource_id.startswith(adj + "-"): 

32 break 

33 else: 

34 return None 

35 

36 return resource_id[len(adj) + 1 :] 

37 

38 def validate_concept_id(self, resource_id: str): 

39 noun = self.get_noun(resource_id) 

40 if noun is None: 

41 raise ValueError( 

42 f"{resource_id} does not start with a listed adjective" 

43 + " (or does not follow the pattern 'adjective-noun')" 

44 ) 

45 

46 if noun not in self.nouns: 

47 raise ValueError( 

48 f"{resource_id} does not end with a listed noun" 

49 + " (or does not follow the pattern 'adjective-noun')" 

50 ) 

51 

52 

53class IdParts(ConfigNode, frozen=True): 

54 """parts to create resource ids""" 

55 

56 model: IdPartsEntry 

57 dataset: IdPartsEntry 

58 notebook: IdPartsEntry 

59 

60 def get_icon(self, resource_id: str): 

61 for parts in (self.model, self.dataset, self.notebook): 

62 noun = parts.get_noun(resource_id) 

63 if noun is not None and noun in parts.nouns: 

64 return parts.nouns[noun] 

65 

66 return None 

67 

68 def __getitem__(self, type_: str) -> IdPartsEntry: 

69 if type_ == "model": 

70 return self.model 

71 elif type_ == "dataset": 

72 return self.dataset 

73 elif type_ == "notebook": 

74 return self.notebook 

75 else: 

76 raise NotImplementedError( 

77 f"handling resource id for type '{type_}' is not yet implemented" 

78 )