Source code for oras.decorator

__author__ = "Vanessa Sochat"
__copyright__ = "Copyright The ORAS Authors."
__license__ = "Apache-2.0"

import time
from functools import partial, update_wrapper

from oras.logger import logger


[docs] class Decorator: """ Shared parent decorator class """ def __init__(self, func): update_wrapper(self, func) self.func = func def __get__(self, obj, objtype): return partial(self.__call__, obj)
[docs] class ensure_container(Decorator): """ Ensure the first argument is a container, and not a string. """ def __call__(self, cls, *args, **kwargs): if "container" in kwargs: kwargs["container"] = cls.get_container(kwargs["container"]) elif args: container = cls.get_container(args[0]) args = (container, *args[1:]) return self.func(cls, *args, **kwargs)
[docs] class classretry(Decorator): """ Retry a function that is part of a class """ def __init__(self, func, attempts=5, timeout=2): super().__init__(func) self.attempts = attempts self.timeout = timeout def __call__(self, cls, *args, **kwargs): attempt = 0 attempts = self.attempts timeout = self.timeout while attempt < attempts: try: return self.func(cls, *args, **kwargs) except Exception as e: sleep = timeout + 3**attempt logger.info(f"Retrying in {sleep} seconds - error: {e}") time.sleep(sleep) attempt += 1 return self.func(cls, *args, **kwargs)
[docs] def retry(attempts, timeout=2): """ A simple retry decorator """ def decorator(func): def inner(*args, **kwargs): attempt = 0 while attempt < attempts: try: return func(*args, **kwargs) except Exception as e: sleep = timeout + 3**attempt logger.info(f"Retrying in {sleep} seconds - error: {e}") time.sleep(sleep) attempt += 1 return func(*args, **kwargs) return inner return decorator