__author__="Vanessa Sochat"__copyright__="Copyright The ORAS Authors."__license__="Apache-2.0"importtimefromfunctoolsimportwrapsimportrequests.exceptionsimportoras.authfromoras.loggerimportlogger
[docs]defensure_container(func):""" Ensure the first argument is a container, and not a string. """@wraps(func)defwrapper(cls,*args,**kwargs):if"container"inkwargs:kwargs["container"]=cls.get_container(kwargs["container"])elifargs:container=cls.get_container(args[0])args=(container,*args[1:])returnfunc(cls,*args,**kwargs)returnwrapper
[docs]defretry(attempts=5,timeout=2):""" A simple retry decorator """defdecorator(func):@wraps(func)definner(*args,**kwargs):attempt=0whileattempt<attempts:try:res=func(*args,**kwargs)ifres.status_code==500:try:msg=res.json()forerrorinmsg.get("errors",[]):ifisinstance(error,dict)and"message"inerror:logger.error(error["message"])exceptException:passraiseValueError(f"Issue with {res.request.url}: {res.reason}")returnresexceptoras.auth.AuthenticationExceptionase:raiseeexcept(requests.exceptions.SSLError,ImportError):raiseexceptExceptionase:sleep=timeout+3**attemptlogger.info(f"Retrying in {sleep} seconds - error: {e}")time.sleep(sleep)attempt+=1returnfunc(*args,**kwargs)returninnerreturndecorator