Coverage for C: \ Users \ peaco \ OneDrive \ Documents \ GitHub \ mt_metadata \ mt_metadata \ common \ person.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-10 00:11 -0800

1# ===================================================== 

2# Imports 

3# ===================================================== 

4from typing import Annotated 

5 

6from pydantic import ( 

7 AliasChoices, 

8 AnyUrl, 

9 EmailStr, 

10 Field, 

11 field_validator, 

12 ValidationInfo, 

13) 

14 

15from mt_metadata import NULL_VALUES 

16from mt_metadata.base import MetadataBase 

17from mt_metadata.common import Comment 

18 

19 

20# ===================================================== 

21class GenericPerson(MetadataBase): 

22 organization: Annotated[ 

23 str | None, 

24 Field( 

25 default=None, 

26 description="Organization full name", 

27 alias=None, 

28 json_schema_extra={ 

29 "units": None, 

30 "required": False, 

31 "examples": ["mt gurus"], 

32 }, 

33 ), 

34 ] 

35 

36 email: Annotated[ 

37 EmailStr | None, 

38 Field( 

39 default=None, 

40 description="Email of the contact person", 

41 alias=None, 

42 json_schema_extra={ 

43 "units": None, 

44 "required": False, 

45 "examples": ["mt.guru@em.org"], 

46 }, 

47 ), 

48 ] 

49 

50 url: Annotated[ 

51 AnyUrl | None | str, 

52 Field( 

53 default=None, 

54 description="URL of the contact person", 

55 alias=None, 

56 json_schema_extra={ 

57 "units": None, 

58 "required": False, 

59 "examples": ["https://em.org"], 

60 }, 

61 ), 

62 ] 

63 

64 comments: Annotated[ 

65 Comment, 

66 Field( 

67 default_factory=Comment, # type: ignore[return-value] 

68 description="Any comments about the person", 

69 alias=None, 

70 json_schema_extra={ 

71 "units": None, 

72 "required": False, 

73 "examples": ["expert digger"], 

74 }, 

75 ), 

76 ] 

77 

78 @field_validator("comments", mode="before") 

79 @classmethod 

80 def validate_comments(cls, value, info: ValidationInfo) -> Comment: 

81 """ 

82 Validate that the value is a valid comment. 

83 """ 

84 if isinstance(value, str | None): 

85 return Comment(value=value) # type: ignore[return-value] 

86 return value 

87 

88 @field_validator("url", mode="before") 

89 @classmethod 

90 def validate_url(cls, value, info: ValidationInfo) -> AnyUrl | None: 

91 """ 

92 Validate that the value is a valid URL. 

93 """ 

94 if isinstance(value, str): 

95 if value in NULL_VALUES: 

96 return None 

97 return AnyUrl(value) 

98 elif isinstance(value, AnyUrl): 

99 return value 

100 elif value is None: 

101 return None 

102 

103 

104class Person(GenericPerson): 

105 name: Annotated[ 

106 str | None, 

107 Field( 

108 default="", 

109 description="Persons name, should be full first and last name.", 

110 validation_alias=AliasChoices("name", "author"), 

111 json_schema_extra={ 

112 "units": None, 

113 "required": True, 

114 "examples": ["person name"], 

115 }, 

116 ), 

117 ] 

118 

119 

120## Its too complicated to have an alias for name, because there is no getter for author 

121## and with serialization it becomes complicates, easiest solution is to make a different 

122## object with a field for author instead of name. 

123 

124 

125class AuthorPerson(GenericPerson): 

126 author: Annotated[ 

127 str | None, 

128 Field( 

129 default="", 

130 description="Persons name, should be full first and last name.", 

131 validation_alias=AliasChoices("author", "name"), 

132 json_schema_extra={ 

133 "units": None, 

134 "required": True, 

135 "examples": ["person name"], 

136 }, 

137 ), 

138 ]