Rate limiting library for Python with sync/async support
Reason this release was yanked:
test package
Project description
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.
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
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()
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()
if __name__ == "__main__":
main()
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}")
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)
if __name__ == "__main__":
asyncio.run(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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flowguard-0.1.0.tar.gz.
File metadata
- Download URL: flowguard-0.1.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b322960c651e42dfbe15fdfa79b78d4b904ca396e5c9706d03cd3fcb9efac11
|
|
| MD5 |
4f7586a6813c5052f18d3ee4162c24cc
|
|
| BLAKE2b-256 |
6cd6adb14e4bee9d34898cf4d289201098c2d75d97e0667002d615aba31d64d9
|
File details
Details for the file flowguard-0.1.0-pp311-pypy311_pp73-win_amd64.whl.
File metadata
- Download URL: flowguard-0.1.0-pp311-pypy311_pp73-win_amd64.whl
- Upload date:
- Size: 332.0 kB
- Tags: PyPy, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9d0f4fa9adf16584d5bddada4321627951b091d60621073402162e0656a5fcd
|
|
| MD5 |
6bab04429bfc1744f359c8ae820e9c90
|
|
| BLAKE2b-256 |
b10588c268cb27fd8ff742895b70b40f83607c0e74b3df836078ee9f40a44fc9
|
File details
Details for the file flowguard-0.1.0-pp310-pypy310_pp73-win_amd64.whl.
File metadata
- Download URL: flowguard-0.1.0-pp310-pypy310_pp73-win_amd64.whl
- Upload date:
- Size: 333.9 kB
- Tags: PyPy, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad32aa1c6b88d709f03c097685516de15ca7d3f1e7379c6d091d81a535c818f9
|
|
| MD5 |
f3feda98b450d4cfcafd87e471ef0222
|
|
| BLAKE2b-256 |
03e60514500752e75ccc78ec0602a0a78587b76e5b69c49f2e1008343a0ba7af
|
File details
Details for the file flowguard-0.1.0-pp39-pypy39_pp73-win_amd64.whl.
File metadata
- Download URL: flowguard-0.1.0-pp39-pypy39_pp73-win_amd64.whl
- Upload date:
- Size: 335.9 kB
- Tags: PyPy, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fae26642d7184a3ece4530bf8a8a6f5a942eb5d381f286096f2023d96fea552
|
|
| MD5 |
8e02caf1e574a8bdaaf8fac9ca868de5
|
|
| BLAKE2b-256 |
8f1f1be76b1c822d44219a0f9132c5550fb58ca7bbb6facd44162472684dcddc
|
File details
Details for the file flowguard-0.1.0-cp313-cp313t-win_arm64.whl.
File metadata
- Download URL: flowguard-0.1.0-cp313-cp313t-win_arm64.whl
- Upload date:
- Size: 317.4 kB
- Tags: CPython 3.13t, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f526716da5635fecbdbcf0e62772fe811da7c2056248bff084341873621b385
|
|
| MD5 |
60537bf388a60aae82ed3cf3f1abc514
|
|
| BLAKE2b-256 |
c5f6802ad64876ec0173954111a9befbd2d99f9e43a95a044080dfdc867362af
|
File details
Details for the file flowguard-0.1.0-cp313-cp313t-win_amd64.whl.
File metadata
- Download URL: flowguard-0.1.0-cp313-cp313t-win_amd64.whl
- Upload date:
- Size: 331.3 kB
- Tags: CPython 3.13t, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecb988ea11983c77ac2fcead3f21385777bba00d22791ad74e4b49b6cf424da0
|
|
| MD5 |
05cedff075cc02a50db389b39dc94b64
|
|
| BLAKE2b-256 |
3880e885a6206937b25b840c8d9e54bab96dbea2578eca3e2a3307676808dc8d
|
File details
Details for the file flowguard-0.1.0-cp38-abi3-win_arm64.whl.
File metadata
- Download URL: flowguard-0.1.0-cp38-abi3-win_arm64.whl
- Upload date:
- Size: 321.5 kB
- Tags: CPython 3.8+, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f80b0057f44734328cefe92bfb9ad8456c7c06ed45cefe3dde454c3f219d6afa
|
|
| MD5 |
9efb28c7dee56bba366fe6e6a4196e77
|
|
| BLAKE2b-256 |
602e120dd5d9a2cd2a1cbf2f9d0f68248bf9d81e2d9caf34cdfe617f5f150979
|
File details
Details for the file flowguard-0.1.0-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: flowguard-0.1.0-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 334.2 kB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7238278697af30c1431fa5f81e7bf4fd602426d67b09321e3d6df80ba06a034
|
|
| MD5 |
ea790e2b1d3f2ef291361582912b8980
|
|
| BLAKE2b-256 |
e01518077c1196e51dd30286a335fb8ba593c3f7bfbe95f2c066283ab895e540
|
File details
Details for the file flowguard-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: flowguard-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 414.8 kB
- Tags: CPython 3.8+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2dc8c5edc915407becdc6d52da464574ce5b7d1980a2dcb177574c0a67c7303
|
|
| MD5 |
3a83666a98ac3486f1e702944d73f67b
|
|
| BLAKE2b-256 |
1cf07162db0cc2d8c89ea96e6591ac8aacf7931af46e3429e8ac2d5729e0b06a
|
File details
Details for the file flowguard-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: flowguard-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 424.4 kB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad39af93ed18f5c10f3bdcdd5d43771399e5e1ae8466b1dae9d9a13cfebd7cf0
|
|
| MD5 |
d3ecdf97f6d44db8b017f971fe8126a7
|
|
| BLAKE2b-256 |
67f154c68a701da8c4c5d6ee18411eb89c7ca0172934e3bf84c76b1219813ddc
|
File details
Details for the file flowguard-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: flowguard-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 412.9 kB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd316fa9420c5f2195690b418d0a662443f4a5548875664ca6f9e20f9879d316
|
|
| MD5 |
3a8c958e79ad38be6c752e05954a4663
|
|
| BLAKE2b-256 |
77e92ab2d831ea1c322f733c1b1cb6b22f1239c76ac1cfc2f874a757307cfa65
|