docs: 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