Debounce and throttle decorators for Python functions.
pip install philiprehberger-debounceDebounce and throttle decorators for Python functions.
pip install philiprehberger-debounce
from philiprehberger_debounce import debounce, throttle
Delay execution until a quiet period has passed. Each new call resets the timer.
@debounce(0.5)
def on_resize(width, height):
print(f"Resized to {width}x{height}")
on_resize(800, 600)
on_resize(1024, 768) # cancels the previous call
# Only the last call executes after 0.5s
Use max_wait to guarantee the function fires at most max_wait seconds after the first pending call, even if calls keep arriving and continuously reset the debounce timer. Mirrors lodash debounce({ maxWait }) semantics.
@debounce(0.5, max_wait=2.0)
def autosave(content):
print(f"Saving: {content[:20]}...")
# Even with continuous edits, autosave fires at least every 2s.
for chunk in stream_keystrokes():
autosave(chunk)
max_wait must be positive and >= seconds; otherwise ValueError is raised.
The wrapper exposes .cancel() (drop any pending trailing call) and .flush() (fire it immediately). Mirrors the lodash debounce control API.
@debounce(0.5)
def save(content):
print(f"saving {content}")
save("draft 1")
save.cancel() # drop the pending call
save("draft 2")
save.flush() # fire immediately, don't wait for the timer
Limit a function to a fixed number of calls within a time window. Excess calls are silently dropped.
@throttle(calls=3, per=1.0)
def send_request(data):
print(f"Sending {data}")
for i in range(10):
send_request(i) # only the first 3 calls within 1s execute
| Decorator | Parameter | Description |
|---|---|---|
debounce(seconds, *, leading=False, max_wait=None) | seconds | Minimum quiet period (in seconds) before the function is invoked. Each new call cancels the previous pending invocation and restarts the timer. |
leading | If True, fire on the leading edge of the window instead of the trailing edge. Subsequent rapid calls are suppressed until seconds of silence have elapsed. | |
max_wait | Optional upper bound (in seconds) on how long the function may be deferred from the first pending call. Must be positive and >= seconds. Mirrors lodash debounce({ maxWait }). | |
wrapper.cancel() | — | Discard any pending trailing invocation and reset leading-edge state. |
wrapper.flush() | — | Fire the pending trailing invocation immediately (no-op if none is pending). |
throttle(calls, per) | calls | Maximum number of allowed invocations within the sliding window. |
per | Length of the sliding window in seconds. Calls beyond calls within per are silently dropped. |
pip install -e .
python -m pytest tests/ -v
If you find this project useful: