Flowguard
Flowguard is a rate limiting library for Python. It provides both synchronous (RateLimiter) and asynchronous (AsyncRateLimiter) classes to manage request rates with flexible time windows (seconds, minutes, hours, days) and optional burst limits.
Features
- Synchronous and Asynchronous Support: Use RateLimiter for blocking operations or AsyncRateLimiter for async/await workflows.
- Customizable Time Windows: Set rate limits per second, minute, hour, or day, with configurable window durations.
- Burst Limiting: Optional maximum burst capacity to control maximum concurrent requests.
- Thread-Safe and Interruptible: Built with atomic operations and mutexes for safe concurrent use.
- Context Manager Support: For automatic resource management.
- Use as a Decorator: For clean and concise rate limiting.
Installation
Flowguard is available as a Python package. Install it using pip:
pip install flowguard
Ensure you have a compatible Python version (3.8 or higher) installed.
Parameters
- sec, min, hour, day: Rate limits for respective time units.
- sec_window, min_window, hour_window, day_window: Custom window durations (in seconds) for respective units. Default is 1.
- blocking: Default True (For using as a context manager). if False, returns immediately if no permit is available.
- max_burst: Optional maximum number of concurrent permits allowed.
Usage
Asynchronous Rate Limiter Example ::
import asyncio
import logging
from flowguard import AsyncRateLimiter
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s.%(msecs)03d %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)
async def explicit_example(i, limiter):
await limiter.acquire()
logger.info(f"Permit acquired for {i}")
# Simulate work
await asyncio.sleep(1)
await limiter.release()
async def context_manager_example(i, limiter):
async with limiter:
logger.info(f"Permit acquired for {i}")
@AsyncRateLimiter(sec=5, max_burst=3, sec_window= 2)
async def decorator_example(i):
logger.info(f"Permit acquired for {i}")
async def main():
limiter = AsyncRateLimiter(sec=10)
print("\n", "Explicit Example".center(60, "="), "\n")
explicit_tasks = [
explicit_example(i, limiter)
for i in range(15)
]
await asyncio.gather(*explicit_tasks)
print("\n", "Context Manager Example".center(60, "="), "\n")
burst_limiter = AsyncRateLimiter(sec=5, max_burst=3, sec_window= 2)
burst_tasks = [
context_manager_example(f"burst-{i}", burst_limiter)
for i in range(15)
]
await asyncio.gather(*burst_tasks)
print("\n", "Decorator Example".center(60, "="), "\n")
tasks = [
decorator_example(i) for i in range(15)
]
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
Synchronous Rate Limiter Example ::
import logging
import threading
from time import sleep
from flowguard import RateLimiter
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s.%(msecs)03d %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)
def non_blocking_example(i, limiter):
permit = limiter.acquire()
if permit:
logger.info(f"Permit acquired for {i}.")
# Simulate work ::
sleep(1)
limiter.release()
else:
logger.info("No permit is available.")
# Here we can do other task when no immediate permit is available
def context_manager_example(i, limiter):
with limiter:
logger.info(f"Permit acquired for {i}.")
# Simulate work ::
sleep(1)
def explicit_example(i, limiter):
# This call will block until it gets a permit
permit = limiter.acquire()
if permit:
logger.info(f"Permit acquired for {i}")
# Simulate work
sleep(1)
limiter.release()
@RateLimiter(sec=3, min=5, sec_window=3, max_burst=2)
def decorator_example(i):
logger.info(f"Permit acquired for {i}")
# Simulate work
sleep(1)
def main():
# This will create a ratelimiter instance with 3 req/2 sec and 15 req/min with a max allowed concurrent req = 2
blocking_limiter = RateLimiter(sec= 3, min= 15, sec_window=2, max_burst= 2)
non_blocking_limiter = RateLimiter(sec= 3, min= 15, sec_window=2, max_burst= 2, blocking=False)
print("Blocking Limiter".center(60, "="), "\n")
print("Using Context Manager".center(60, "="), "\n")
threads = []
for i in range(30):
t = threading.Thread(target=context_manager_example, args=(i, blocking_limiter), daemon= True)
threads.append(t)
t.start()
# Waiting for the work to finish oktherwise both function output will be mixed
for t in threads:
t.join()
blocking_limiter = RateLimiter(sec= 3, min= 15, sec_window=2, max_burst= 2)
print("\n", "Explicit acquire/ release".center(60, "="), "\n")
threads = []
for i in range(30):
t = threading.Thread(target=explicit_example, args=(i, blocking_limiter), daemon= True)
threads.append(t)
t.start()
for t in threads:
t.join()
print("\n", "Non-Blocking Mode".center(60, "="), "\n")
threads = []
for i in range(30):
t = threading.Thread(target=non_blocking_example, args=(i, non_blocking_limiter), daemon= True)
threads.append(t)
t.start()
# Without the sleep it will give permit = max_burst count and all other threads will failed to acquire any permit
sleep(.1)
for t in threads:
t.join()
print("\n", "Using as a Decorator".center(60, "="), "\n")
threads = []
for i in range(30):
t = threading.Thread(target=decorator_example, args=(i, ), daemon= True)
threads.append(t)
t.start()
for t in threads:
t.join()
if __name__ == "__main__":
main()
License
Flowguard is licensed under the MIT License. See the LICENSE file for details.
Contributing
Contributions are welcome! Feel free to submit pull requests, report issues, or suggest improvements.
Release files for flowguard 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| flowguard-0.1.3.tar.gz | 19.1 kB | Details |
Built distributions (wheels)
Total release size: 6.9 MB
Release files / flowguard-0.1.3.tar.gz
| Download URL | flowguard-0.1.3.tar.gz |
|---|---|
| Size | 19.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fea13357b2f8be2dd754db13990b5608cf3a54fbda7a50f3bb9f5ccf71e04334
|
|
BLAKE2b-256 checksum How to use checksums |
d5982688bbaa3a4594233b003c4df25935a716f0f90a9d6cda74caf756aca5de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-win_amd64.whl
| Download URL | flowguard-0.1.3-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 371.6 kB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0e5ae8979ef7d4f598792a90b3cbbdacbdfe3920ed23f44936dd64fd202bcfc9
|
|
BLAKE2b-256 checksum How to use checksums |
c1a901362e5a4aa59eb0db7452ce45aa6658c4e37449478c2dc86a3f5b18dec2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-win32.whl
| Download URL | flowguard-0.1.3-cp38-abi3-win32.whl |
|---|---|
| Size | 340.4 kB |
| Tags | CPython 3.8 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
6a1085790c68867a8b25cbb2f357408e856d6c2a631ac2b776e88814503a1973
|
|
BLAKE2b-256 checksum How to use checksums |
515a1cc3fab3979145f45dd0f9651e28aba4fb9cf9f33fa3280fd72491305f1d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-musllinux_1_2_x86_64.whl
| Download URL | flowguard-0.1.3-cp38-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 616.6 kB |
| Tags | CPython 3.8 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
9470106c9614e1eec114554ebd43a67f3d2be78d71ea6442c4262cd06decf311
|
|
BLAKE2b-256 checksum How to use checksums |
dd205557f3cb3e9ea20999c8d5c9ed2d3329e446a710fb048dd588161f2550da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-musllinux_1_2_i686.whl
| Download URL | flowguard-0.1.3-cp38-abi3-musllinux_1_2_i686.whl |
|---|---|
| Size | 652.4 kB |
| Tags | CPython 3.8 Linux musl 1.2+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
1544f69d5d9e47865167344305299086c2179ae23381d575e79ceacb376adbed
|
|
BLAKE2b-256 checksum How to use checksums |
6ddfa2a17bb3412921799481b9f6c131871d6253fe82a36bb73d5fcf3d7fc7fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-musllinux_1_2_armv7l.whl
| Download URL | flowguard-0.1.3-cp38-abi3-musllinux_1_2_armv7l.whl |
|---|---|
| Size | 708.1 kB |
| Tags | CPython 3.8 Linux musl 1.2+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
83f6509d40f33dcc92c82416d2a43ca8c3b37761e6c656aa0c5505997d57c059
|
|
BLAKE2b-256 checksum How to use checksums |
442c24c37140d7e1fd188fd3e8791866b01658cbbf732602138e7ae1bae4e175
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-musllinux_1_2_aarch64.whl
| Download URL | flowguard-0.1.3-cp38-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 602.1 kB |
| Tags | CPython 3.8 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
d55d23200314b03ef25e66d94c37554b16a77ce4c195100353ca1aceadf2ad42
|
|
BLAKE2b-256 checksum How to use checksums |
2a4b0f1bd55feb9382ae180903b5ca7154dc41e76707e9d1af1eff52720f9556
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | flowguard-0.1.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 444.4 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
3af78b184aa4dd27cab4cd5fde05eac87f17d212a591b56e74a205fe193962d3
|
|
BLAKE2b-256 checksum How to use checksums |
66321a46b88ddba1acf5fcde29ad1261d8417c66012a6ccbc71ecf029ae94448
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
| Download URL | flowguard-0.1.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl |
|---|---|
| Size | 511.5 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ IBM System/390x abi3 |
|
SHA-256 checksum How to use checksums |
ab9707c7a0ebf067c04bc0069cf96b1ee5ec1b0a40e5058b1f7bb7f2355324bc
|
|
BLAKE2b-256 checksum How to use checksums |
39590929e81cdfa58c45ad9cf84e52600a816e6ccf650ce49a12303f2fe1fc64
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| Download URL | flowguard-0.1.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl |
|---|---|
| Size | 483.3 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ PowerPC 64-le abi3 |
|
SHA-256 checksum How to use checksums |
0e4a5e1e4d22718723dadc49429c3e0a345aa2ab4e13e9bdf38bd40b255835b4
|
|
BLAKE2b-256 checksum How to use checksums |
dc21867e0675e56de7acf96041c9e8185cd817cbdc91f1b37c6188a12d0f0f70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| Download URL | flowguard-0.1.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl |
|---|---|
| Size | 444.5 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
e7968a0c30eea2b0ba003013578e9b2eeae166da7a799d2d508c20a6cbcf0647
|
|
BLAKE2b-256 checksum How to use checksums |
919466d28734a4237fcab308edee5ee121adc3674a961869f6bd2cc3bccc2404
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | flowguard-0.1.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 429.3 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
de3d1b03d26155e50e85aa8d732c02b202864c3bf00784d69970376f4abde607
|
|
BLAKE2b-256 checksum How to use checksums |
6715c97a344797c0434f8069bb30ded3b72493c1f9b06a81265204d9bcd1d562
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
| Download URL | flowguard-0.1.3-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.whl |
|---|---|
| Size | 474.2 kB |
| Tags | CPython 3.8 Linux glibc 2.12+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
8e68bb085f10f62616dcc2a0450e62392558acc0c05821635bd99b586b1677d8
|
|
BLAKE2b-256 checksum How to use checksums |
55d0a5454ee112fd9416420adc43d69b52bf540f8e0747acf28accae2ad1fe19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | flowguard-0.1.3-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 399.9 kB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
e5734ade930817bb88ea2e1002007de1504e44269d5d713d08fbfc2cf1045933
|
|
BLAKE2b-256 checksum How to use checksums |
22515514bc1898053ce28205d848ecf9e51fb7391a6a06d54d15fa1ccfe95c9d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|
Release files / flowguard-0.1.3-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | flowguard-0.1.3-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 421.2 kB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
c1f4f738dd0321ba3471f6fff5c65ef47eb1b8cde3263ba5884daf8e25f5842a
|
|
BLAKE2b-256 checksum How to use checksums |
f07a56c7abf72f42a7bc7a5b0481041631b2168c2a032786f9b0ceaea70cbe0a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.8.7
|