Note: Modify and use as needed. Suggestions for improvements are welcome!
""" Usage:
from uuid import UUID
print(check_mandatory_params(
{"score": 7.5, "id": "e76cbfa0-06e6-4ad9-8209-3ae786cf344d", "name": "John" },
[
("score", float),
("id", UUID),
("name", str),
("status", lambda x: x in ["resolved", "pending"], False, "Status needs to be one of 'resolved', 'pending'"),
("age", lambda item: isinstance(item, int) and item >= 18, False, "Applicant must be of legal age")
],
))
>> {"success": True}
print(check_mandatory_params(
{"id": "e76cbfa0-06e6-4ad9-8209-3ae786cf344d", "name": "John" },
[
("score", float, True),
("id", UUID),
("name", str),
("status", lambda x: x in ["resolved", "pending"], False, "Status needs to be one of 'resolved', 'pending'"),
("age", lambda item: isinstance(item, int) and item >= 18, False, "Applicant must be of legal age")
]
))
>> {'success': False, 'message': 'score is missing'}
"""
def check_mandatory_params(
params: Dict[str, Any],
mandatory_attributes: List[
Union[Tuple[str, type], Tuple[str, type, bool], Tuple[str, type, bool, str]]
] = [],
) -> Dict[str, Any]:
for attr in mandatory_attributes:
attr_name = attr[0]
attr_type = attr[1]
is_mandatory = attr[2] if len(attr) > 2 else True
error_msg = attr[3] if len(attr) > 3 else None
if is_mandatory and attr_name not in params:
return {"success": False, "message": f"{attr_name} is missing"}
if attr_name in params:
value = params[attr_name]
if callable(attr_type) and attr_type.__name__ == "<lambda>":
if not attr_type(value):
return {
"success": False,
"message": error_msg
or f"Invalid data format for '{attr_name}'",
}
elif not isinstance(value, attr_type):
return {
"success": False,
"message": error_msg
or f"{attr_name} is not of type {attr_type.__name__}",
}
return {"success": True}
import uuid
def is_valid_uuid(value):
try:
uuid.UUID(str(value))
return True
except Exception:
return False
def dotsplitgen(string):
"""
generator version of str.split(".")
"""
buffer = ""
for character in string:
if character == ".":
temp_buff = buffer + ""
buffer = ""
if temp_buff == "":
continue
yield temp_buff
continue
buffer+=character
else:
if buffer!="":
yield buffer
def hasattr_nested(obj, path):
"""
Check presence of nested attributes
"""
for item in dotsplitgen(path):
if hasattr(obj, item):
obj = getattr(obj, item, None)
else:
break
else:
return True
return False