1- import uuid
21from functools import wraps
3- from pathlib import Path
4- from typing import Optional
52from typing import Union
63
7- from lib .core .enums import AnnotationStatus
8- from lib .core .enums import ApprovalStatus
94from lib .core .enums import BaseTitledEnum
10- from lib .core .enums import ClassTypeEnum
11- from lib .core .enums import FolderStatus
12- from lib .core .enums import ProjectStatus
13- from lib .core .enums import ProjectType
14- from lib .core .enums import UserRole
155from lib .core .exceptions import AppException
166from lib .infrastructure .validators import wrap_error
17- from pydantic import BaseModel
18- from pydantic import conlist
197from pydantic import constr
208from pydantic import errors
21- from pydantic import Extra
22- from pydantic import Field
23- from pydantic import parse_obj_as
24- from pydantic import root_validator
259from pydantic import StrictStr
2610from pydantic import validate_arguments as pydantic_validate_arguments
2711from pydantic import ValidationError
2812from pydantic .errors import PydanticTypeError
2913from pydantic .errors import StrRegexError
3014
31- NotEmptyStr = constr (strict = True , min_length = 1 )
32-
3315
3416class EnumMemberError (PydanticTypeError ):
3517 code = "enum"
@@ -54,174 +36,20 @@ def validate(cls, value: Union[str]) -> Union[str]:
5436 regex = r"^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)"
5537 r"*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}"
5638 r"[a-zA-Z0-9])?)*$"
57- ).validate (value )
39+ ).validate ( # noqa
40+ value
41+ )
5842 except StrRegexError :
5943 raise ValueError ("Invalid email" )
6044 return value
6145
6246
63- class ProjectStatusEnum (StrictStr ):
64- @classmethod
65- def validate (cls , value : Union [str ]) -> Union [str ]:
66- if cls .curtail_length and len (value ) > cls .curtail_length :
67- value = value [: cls .curtail_length ]
68- if value .lower () not in ProjectStatus .values ():
69- raise TypeError (
70- f"Available statuses is { ', ' .join (ProjectStatus .titles ())} . "
71- )
72- return value
73-
74-
75- class FolderStatusEnum (StrictStr ):
76- @classmethod
77- def validate (cls , value : Union [str ]) -> Union [str ]:
78- if cls .curtail_length and len (value ) > cls .curtail_length :
79- value = value [: cls .curtail_length ]
80- if value .lower () not in FolderStatus .values ():
81- raise TypeError (
82- f"Available statuses is { ', ' .join (FolderStatus .titles ())} . "
83- )
84- return value
85-
86-
87- class AnnotatorRole (StrictStr ):
88- ANNOTATOR_ROLES = (UserRole .ADMIN .name , UserRole .ANNOTATOR .name , UserRole .QA .name )
89-
90- @classmethod
91- def validate (cls , value : Union [str ]) -> Union [str ]:
92- if cls .curtail_length and len (value ) > cls .curtail_length :
93- value = value [: cls .curtail_length ]
94- if value .lower () not in [role .lower () for role in cls .ANNOTATOR_ROLES ]:
95- raise TypeError (
96- f"Invalid user role provided. Please specify one of { ', ' .join (cls .ANNOTATOR_ROLES )} . "
97- )
98- return value
99-
100-
101- class AnnotationType (StrictStr ):
102- VALID_TYPES = ["bbox" , "polygon" , "point" , "tag" ]
103-
104- @classmethod
105- def validate (cls , value : Union [str ]) -> Union [str ]:
106- if value .lower () not in cls .VALID_TYPES :
107- raise TypeError (
108- f"Available annotation_types are { ', ' .join (cls .VALID_TYPES )} . "
109- )
110- return value
111-
112-
113- class AttachmentDict (BaseModel ):
114- url : StrictStr
115- name : Optional [StrictStr ] = Field (default_factory = lambda : str (uuid .uuid4 ()))
116-
117- class Config :
118- extra = Extra .ignore
119-
120- def __hash__ (self ):
121- return hash (self .name )
122-
123- def __eq__ (self , other ):
124- return self .url == other .url and self .name .strip () == other .name .strip ()
125-
126-
127- AttachmentArgType = Union [NotEmptyStr , Path , conlist (AttachmentDict , min_items = 1 )]
128-
129-
130- class Setting (BaseModel ):
131- attribute : NotEmptyStr
132- value : Union [NotEmptyStr , float , int ]
133-
134- class Config :
135- extra = Extra .ignore
136-
137-
138- class AttachmentArg (BaseModel ):
139- __root__ : AttachmentArgType
140-
141- def __getitem__ (self , index ):
142- return self .__root__ [index ]
143-
144- @property
145- def data (self ):
146- return self .__root__
147-
148- @root_validator (pre = True )
149- def validate_root (cls , values ):
150- try :
151- parse_obj_as (AttachmentArgType , values ["__root__" ])
152- except ValidationError :
153- raise ValueError (
154- "The value must be str, path, or list of dicts with the required 'url' and optional 'name' keys"
155- )
156- return values
157-
158-
159- class ImageQualityChoices (StrictStr ):
160- VALID_CHOICES = ["compressed" , "original" ]
161-
162- @classmethod
163- def validate (cls , value : Union [str ]) -> Union [str ]:
164- super ().validate (value )
165- if value .lower () not in cls .VALID_CHOICES :
166- raise TypeError (
167- f"Image quality available choices are { ', ' .join (cls .VALID_CHOICES )} ."
168- )
169- return value .lower ()
170-
171-
172- class ProjectTypes (StrictStr ):
173- @classmethod
174- def validate (cls , value : Union [str ]) -> Union [str ]:
175- if value .lower () not in ProjectType .values ():
176- raise TypeError (
177- f" Available project types are { ', ' .join (ProjectType .titles ())} . "
178- )
179- return value
180-
181-
182- class ClassType (StrictStr ):
183- @classmethod
184- def validate (cls , value : Union [str ]) -> Union [str ]:
185- enum_values = [e .name .lower () for e in ClassTypeEnum ]
186- if value .lower () not in enum_values :
187- raise TypeError (
188- f"Invalid type provided. Please specify one of the { ', ' .join (enum_values )} . "
189- )
190- return value .lower ()
191-
192-
193- class AnnotationStatuses (StrictStr ):
194- @classmethod
195- def validate (cls , value : Union [str ]) -> Union [str ]:
196- if value .lower () not in AnnotationStatus .values ():
197- raise TypeError (
198- f"Available an notation_statuses are { ', ' .join (AnnotationStatus .titles ())} . "
199- )
200- return value
201-
202-
203- class ApprovalStatuses (StrictStr ):
204- @classmethod
205- def validate (cls , value : Union [str ]) -> Union [str ]:
206- if value is None :
207- return value
208- if value .lower () not in ApprovalStatus .values () or not isinstance (value , str ):
209- raise TypeError (
210- f"Available approval_status options are { ', ' .join (map (str , ApprovalStatus .titles ()))} ."
211- )
212- return value
213-
214- @classmethod
215- def __get_validators__ (cls ):
216- yield cls .validate
217-
218-
21947def validate_arguments (func ):
22048 @wraps (func )
22149 def wrapped (self , * args , ** kwargs ):
22250 try :
22351 return pydantic_validate_arguments (func )(self , * args , ** kwargs )
22452 except ValidationError as e :
225- raise AppException (wrap_error (e ))
53+ raise AppException (wrap_error (e )) from e
22654
22755 return wrapped
0 commit comments