"""Job utilities.""" from datetime import timedelta import functools import time from typing import List import config from logger import logger def handle_errors(custom_handler=None): """Retry on db errors. Args: custom_handler: Custom error handling function. """ def inner(f): def wrapped(*args, **kwargs): for i in range(1, config.RETRY_COUNT + 1): try: return f(*args, **kwargs) except Exception as ex: if i != config.RETRY_COUNT: logger.info(f"Retry on error: {ex}") if custom_handler: custom_handler(*args, **kwargs) time.sleep(i * config.RETRY_WAIT_RATE) else: logger.info(ex) raise ex return wrapped return inner def timing(f): """Log execution time. """ @functools.wraps(f) def wrapper(*args, **kwargs): start_time = time.time() result = f(*args, **kwargs) elapsed_time = time.time() - start_time logger.debug(f"{f.__name__}: {timedelta(seconds=elapsed_time)}") return result return wrapper def max_playlist_id(playlist_ids: List[str]) -> str: """Get max playlist ID from a list case insensitive. Args: playlist_ids (List[str]): Set of playlist ID. Returns: str: Max playlist ID. """ max_id = "" for pl_id in playlist_ids: if max_id.lower() < pl_id.lower(): max_id = pl_id return max_id