Source: https://github.com/tomasbasham/ratelimit/tree/0ca5a616fa6d184fa180b9ad0b6fd0cf54c46936
    Need to make a few changes that included having num_calls be a float

    Prevent a method from being called
    if it was previously called before
    a time widows has elapsed.

    Keyword Arguments:
        num_calls (float): Maximum method invocations within a period. Must be greater than 0.
        every (float): A dampening factor (in seconds). Can be any number greater than 0.

    Return:
        function: Decorated function that will forward method invocations if the time window has elapsed.

def rate_limited(num_calls=1, every=1.0):
    """
    Source: https://github.com/tomasbasham/ratelimit/tree/0ca5a616fa6d184fa180b9ad0b6fd0cf54c46936
    Need to make a few changes that included having num_calls be a float

    Prevent a method from being called
    if it was previously called before
    a time widows has elapsed.

    Keyword Arguments:
        num_calls (float): Maximum method invocations within a period. Must be greater than 0.
        every (float): A dampening factor (in seconds). Can be any number greater than 0.

    Return:
        function: Decorated function that will forward method invocations if the time window has elapsed.

    """
    frequency = abs(every) / float(num_calls)
    def decorator(func):
        """
        Extend the behaviour of the following
        function, forwarding method invocations
        if the time window hes elapsed.
        Arguments:
            func (function): The function to decorate

        Returns:
            function: Decorated function

        """

        # To get around issues with function local scope
        # and reassigning variables, we wrap the time
        # within a list. When updating the value we're
        # not reassigning `last_called`, which would not
        # work, but instead reassigning the value at a
        # particular index.
        last_called = [0.0]

        # Add thread safety
        lock = threading.RLock()

        def wrapper(*args, **kargs):
            """Decorator wrapper function"""
            with lock:
                elapsed = time.time() - last_called[0]
                left_to_wait = frequency - elapsed
                if left_to_wait > 0:
                    time.sleep(left_to_wait)
                last_called[0] = time.time()
            return func(*args, **kargs)
        return wrapper
    return decorator