def memoize(ttl=None):
    """ Cache the result of the function call with given args for until
        ttl (datetime.timedelta) expires.
    """
    def decorator(obj):
        cache = obj.cache = {}

        @functools.wraps(obj)
        def memoizer(*args, **kwargs):
            now = datetime.now()
            key = str(args) + str(kwargs)
            if key not in cache:
                cache[key] = (obj(*args, **kwargs), now)
            value, last_update = cache[key]
            if ttl and (now - last_update) > ttl:
                cache[key] = (obj(*args, **kwargs), now)
            return cache[key][0]
        return memoizer
    return decorator