首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将超时和重试修饰函数应用于python中的google-cloud-storage客户端?

如何将超时和重试修饰函数应用于python中的google-cloud-storage客户端?
EN

Stack Overflow用户
提问于 2019-11-16 06:44:27
回答 2查看 737关注 0票数 1

我想要更改Google Cloud Storage请求的默认超时和重试次数,并且可以看到api_core目录中的google cloud包中有装饰器函数,我如何将这些函数应用于存储客户端(如果这是正确的术语)?

代码语言:javascript
复制
from google.cloud import storage
from google.api_core import timeout

timeout_ = timeout.ConstantTimeout(timeout=600)
storage_client = storage.Client()
storage_client.get_bucket(name_of_bucket)
EN

回答 2

Stack Overflow用户

发布于 2019-11-20 19:15:43

这里您有一个基于api_core文件夹的自定义解决方案。不同之处在于func_with_timeout函数。通过这种方式,它可以为要包装的函数配置指定的超时和重试次数。

代码语言:javascript
复制
import functools
import signal
from multiprocessing import TimeoutError

import six
from google.cloud import storage


_PARTIAL_VALID_ASSIGNMENTS = ("__doc__",)


def wraps(wrapped):
    """A functools.wraps helper that handles partial objects on Python 2."""
    # https://github.com/google/pytype/issues/322
    if isinstance(wrapped, functools.partial):  # pytype: disable=wrong-arg-types
        return six.wraps(wrapped, assigned=_PARTIAL_VALID_ASSIGNMENTS)
    else:
        return six.wraps(wrapped)


def raise_timeout(signum, frame):
    raise TimeoutError


@six.python_2_unicode_compatible
class ConstantTimeout(object):
    """A decorator that adds a constant timeout argument.

    This is effectively equivalent to
    ``functools.partial(func, timeout=timeout)``.

    Args:
        timeout (Optional[float]): the timeout (in seconds) to applied to the
            wrapped function. If `None`, the target function is expected to
            never timeout.
    """

    def __init__(self, timeout=None, retries=None):
        self._timeout = timeout
        self._retries = retries

    def __call__(self, func):
        """Apply the timeout decorator.

        Args:
            func (Callable): The function to apply the timeout argument to.
                This function must accept a timeout keyword argument.

        Returns:
            Callable: The wrapped function.
        """

        @wraps(func)
        def func_with_timeout(*args, **kwargs):
            """Wrapped function that adds timeout."""
            signal.signal(signal.SIGALRM, raise_timeout)

            i = 1
            while i <= self._retries:
                try:
                    # Schedule the signal to be sent after ``time``.
                    signal.alarm(self._timeout)
                    return func(*args, **kwargs)

                except TimeoutError:
                    i += 1
                    pass

            return TimeoutError("Exceed maximum amount of retries: {}".format(self._retries))

        return func_with_timeout

    def __str__(self):
        return "<ConstantTimeout timeout={:.1f}>".format(self._timeout)

然后,您只需创建一个新函数,将您想要包装的函数作为参数传递给timeout_装饰器:

代码语言:javascript
复制
timeout_ = ConstantTimeout(timeout=2, retries=3)
storage_client = storage.Client()
get_bucket_with_timeout = timeout_(storage_client.get_bucket)
buck = get_bucket_with_timeout(name_of_bucket)
print(buck)
票数 1
EN

Stack Overflow用户

发布于 2020-04-17 10:37:03

只需将超时时间作为第二个参数传递:

代码语言:javascript
复制
storage_client.get_bucket(name_of_bucket,120)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58885646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档