Coverage for src/bioimageio/spec/generic/_v0_2_converter.py: 82%

74 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-18 09:17 +0000

1from __future__ import annotations 

2 

3import collections.abc 

4from typing import Any, Mapping 

5 

6from .._internal.io import BioimageioYamlContent 

7from .._internal.type_guards import is_mapping 

8 

9 

10def convert_from_older_format(data: BioimageioYamlContent) -> None: 

11 """convert raw RDF data of an older format where possible""" 

12 # check if we have future format version 

13 if "format_version" not in data: 

14 return 

15 

16 fv = data["format_version"] 

17 if isinstance(fv, str) and tuple(map(int, fv.split(".")[:2])) > (0, 2): 

18 return 

19 

20 # we unofficially accept strings as author entries 

21 authors = data.get("authors") 

22 if isinstance(authors, list): 

23 data["authors"] = [{"name": a} if isinstance(a, str) else a for a in authors] 

24 

25 if data.get("format_version") in ("0.2.0", "0.2.1"): 

26 data["format_version"] = "0.2.2" 

27 

28 if data.get("format_version") == "0.2.2": 

29 remove_slashes_from_names(data) 

30 data["format_version"] = "0.2.3" 

31 

32 if data.get("format_version") == "0.2.3": 

33 if isinstance(config := data.get("config"), dict) and isinstance( 

34 bconfig := config.get("bioimageio"), dict 

35 ): 

36 if (nickname := bconfig.get("nickname")) is not None: 

37 data["id"] = nickname 

38 

39 if (nickname_icon := bconfig.get("nickname_icon")) is not None: 

40 data["id_emoji"] = nickname_icon 

41 

42 data["format_version"] = "0.2.4" 

43 

44 remove_doi_prefix(data) 

45 remove_gh_prefix(data) 

46 

47 

48def remove_slashes_from_names(data: dict[Any, Any]) -> None: 

49 NAME = "name" 

50 if NAME in data and isinstance(data[NAME], str): 

51 data[NAME] = data[NAME].replace("/", "").replace("\\", "") 

52 

53 # update authors and maintainers 

54 def rm_slashes_in_person_name( 

55 person: Any | Mapping[Any | str, Any], 

56 ) -> Any: 

57 if not is_mapping(person): 

58 return person 

59 

60 new_person = dict(person) 

61 if isinstance(n := person.get(NAME), str): 

62 new_person[NAME] = n.replace("/", "").replace("\\", "") 

63 

64 return new_person 

65 

66 for group in ("authors", "maintainers"): 

67 persons = data.get(group) 

68 if isinstance(persons, collections.abc.Sequence): 

69 data[group] = [rm_slashes_in_person_name(p) for p in persons] # type: ignore 

70 

71 

72DOI_PREFIXES = ("https://doi.org/", "http://dx.doi.org/") 

73 

74 

75def remove_doi_prefix(data: BioimageioYamlContent) -> None: 

76 """we unofficially accept DOIs starting with "https://doi.org/" here we remove this prefix""" 

77 cite = data.get("cite") 

78 if isinstance(cite, collections.abc.Sequence): 

79 new_cite = list(cite) 

80 for i in range(len(new_cite)): 

81 cite_entry = new_cite[i] 

82 if not isinstance(cite_entry, collections.abc.Mapping): 

83 continue 

84 

85 doi = cite_entry.get("doi") 

86 if not isinstance(doi, str): 

87 continue 

88 

89 for doi_prefix in DOI_PREFIXES: 

90 if doi.startswith(doi_prefix): 

91 doi = doi[len(doi_prefix) :] 

92 break 

93 else: 

94 continue 

95 

96 new_cite_entry = dict(cite_entry) 

97 new_cite_entry["doi"] = doi 

98 new_cite[i] = new_cite_entry 

99 

100 data["cite"] = new_cite 

101 

102 

103def remove_gh_prefix(data: BioimageioYamlContent) -> None: 

104 def rm_gh(field_name: str): 

105 authors = data.get(field_name) 

106 if not isinstance(authors, list): 

107 return 

108 

109 for a in authors: 

110 if ( 

111 isinstance(a, dict) 

112 and "github_user" in a 

113 and isinstance(a["github_user"], str) 

114 and a["github_user"].startswith("https://github.com/") 

115 ): 

116 a["github_user"] = a["github_user"][len("https://github.com/") :] 

117 

118 rm_gh("authors") 

119 rm_gh("maintainers")