Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flowguard-0.1.0.tar.gz (16.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

flowguard-0.1.0-pp311-pypy311_pp73-win_amd64.whl (332.0 kB view details)

Uploaded PyPyWindows x86-64

flowguard-0.1.0-pp310-pypy310_pp73-win_amd64.whl (333.9 kB view details)

Uploaded PyPyWindows x86-64

flowguard-0.1.0-pp39-pypy39_pp73-win_amd64.whl (335.9 kB view details)

Uploaded PyPyWindows x86-64

flowguard-0.1.0-cp313-cp313t-win_arm64.whl (317.4 kB view details)

Uploaded CPython 3.13tWindows ARM64

flowguard-0.1.0-cp313-cp313t-win_amd64.whl (331.3 kB view details)

Uploaded CPython 3.13tWindows x86-64

flowguard-0.1.0-cp38-abi3-win_arm64.whl (321.5 kB view details)

Uploaded CPython 3.8+Windows ARM64

flowguard-0.1.0-cp38-abi3-win_amd64.whl (334.2 kB view details)

Uploaded CPython 3.8+Windows x86-64

flowguard-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl (414.8 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.34+ x86-64

flowguard-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (424.4 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

flowguard-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (412.9 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

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

Hashes for flowguard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2b322960c651e42dfbe15fdfa79b78d4b904ca396e5c9706d03cd3fcb9efac11
MD5 4f7586a6813c5052f18d3ee4162c24cc
BLAKE2b-256 6cd6adb14e4bee9d34898cf4d289201098c2d75d97e0667002d615aba31d64d9

See more details on using hashes here.

File details

Details for the file flowguard-0.1.0-pp311-pypy311_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.0-pp311-pypy311_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 f9d0f4fa9adf16584d5bddada4321627951b091d60621073402162e0656a5fcd
MD5 6bab04429bfc1744f359c8ae820e9c90
BLAKE2b-256 b10588c268cb27fd8ff742895b70b40f83607c0e74b3df836078ee9f40a44fc9

See more details on using hashes here.

File details

Details for the file flowguard-0.1.0-pp310-pypy310_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.0-pp310-pypy310_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 ad32aa1c6b88d709f03c097685516de15ca7d3f1e7379c6d091d81a535c818f9
MD5 f3feda98b450d4cfcafd87e471ef0222
BLAKE2b-256 03e60514500752e75ccc78ec0602a0a78587b76e5b69c49f2e1008343a0ba7af

See more details on using hashes here.

File details

Details for the file flowguard-0.1.0-pp39-pypy39_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.0-pp39-pypy39_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 9fae26642d7184a3ece4530bf8a8a6f5a942eb5d381f286096f2023d96fea552
MD5 8e02caf1e574a8bdaaf8fac9ca868de5
BLAKE2b-256 8f1f1be76b1c822d44219a0f9132c5550fb58ca7bbb6facd44162472684dcddc

See more details on using hashes here.

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

Hashes for flowguard-0.1.0-cp313-cp313t-win_arm64.whl
Algorithm Hash digest
SHA256 4f526716da5635fecbdbcf0e62772fe811da7c2056248bff084341873621b385
MD5 60537bf388a60aae82ed3cf3f1abc514
BLAKE2b-256 c5f6802ad64876ec0173954111a9befbd2d99f9e43a95a044080dfdc867362af

See more details on using hashes here.

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

Hashes for flowguard-0.1.0-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 ecb988ea11983c77ac2fcead3f21385777bba00d22791ad74e4b49b6cf424da0
MD5 05cedff075cc02a50db389b39dc94b64
BLAKE2b-256 3880e885a6206937b25b840c8d9e54bab96dbea2578eca3e2a3307676808dc8d

See more details on using hashes here.

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

Hashes for flowguard-0.1.0-cp38-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 f80b0057f44734328cefe92bfb9ad8456c7c06ed45cefe3dde454c3f219d6afa
MD5 9efb28c7dee56bba366fe6e6a4196e77
BLAKE2b-256 602e120dd5d9a2cd2a1cbf2f9d0f68248bf9d81e2d9caf34cdfe617f5f150979

See more details on using hashes here.

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

Hashes for flowguard-0.1.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 e7238278697af30c1431fa5f81e7bf4fd602426d67b09321e3d6df80ba06a034
MD5 ea790e2b1d3f2ef291361582912b8980
BLAKE2b-256 e01518077c1196e51dd30286a335fb8ba593c3f7bfbe95f2c066283ab895e540

See more details on using hashes here.

File details

Details for the file flowguard-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 f2dc8c5edc915407becdc6d52da464574ce5b7d1980a2dcb177574c0a67c7303
MD5 3a83666a98ac3486f1e702944d73f67b
BLAKE2b-256 1cf07162db0cc2d8c89ea96e6591ac8aacf7931af46e3429e8ac2d5729e0b06a

See more details on using hashes here.

File details

Details for the file flowguard-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ad39af93ed18f5c10f3bdcdd5d43771399e5e1ae8466b1dae9d9a13cfebd7cf0
MD5 d3ecdf97f6d44db8b017f971fe8126a7
BLAKE2b-256 67f154c68a701da8c4c5d6ee18411eb89c7ca0172934e3bf84c76b1219813ddc

See more details on using hashes here.

File details

Details for the file flowguard-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 cd316fa9420c5f2195690b418d0a662443f4a5548875664ca6f9e20f9879d316
MD5 3a8c958e79ad38be6c752e05954a4663
BLAKE2b-256 77e92ab2d831ea1c322f733c1b1cb6b22f1239c76ac1cfc2f874a757307cfa65

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page