Skip to main content

Rate limiting library for Python with sync/async support

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.
  • 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.

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.3.tar.gz (19.1 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.3-cp38-abi3-win_amd64.whl (371.6 kB view details)

Uploaded CPython 3.8+Windows x86-64

flowguard-0.1.3-cp38-abi3-win32.whl (340.4 kB view details)

Uploaded CPython 3.8+Windows x86

flowguard-0.1.3-cp38-abi3-musllinux_1_2_x86_64.whl (616.6 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ x86-64

flowguard-0.1.3-cp38-abi3-musllinux_1_2_i686.whl (652.4 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ i686

flowguard-0.1.3-cp38-abi3-musllinux_1_2_armv7l.whl (708.1 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ ARMv7l

flowguard-0.1.3-cp38-abi3-musllinux_1_2_aarch64.whl (602.1 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ ARM64

flowguard-0.1.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (444.4 kB view details)

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

flowguard-0.1.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl (511.5 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ s390x

flowguard-0.1.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (483.3 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ppc64le

flowguard-0.1.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (444.5 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARMv7l

flowguard-0.1.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (429.3 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

flowguard-0.1.3-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.whl (474.2 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.12+ i686

flowguard-0.1.3-cp38-abi3-macosx_11_0_arm64.whl (399.9 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

flowguard-0.1.3-cp38-abi3-macosx_10_12_x86_64.whl (421.2 kB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file flowguard-0.1.3.tar.gz.

File metadata

  • Download URL: flowguard-0.1.3.tar.gz
  • Upload date:
  • Size: 19.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.8.7

File hashes

Hashes for flowguard-0.1.3.tar.gz
Algorithm Hash digest
SHA256 fea13357b2f8be2dd754db13990b5608cf3a54fbda7a50f3bb9f5ccf71e04334
MD5 774d06994afd4783232365f103655a3f
BLAKE2b-256 d5982688bbaa3a4594233b003c4df25935a716f0f90a9d6cda74caf756aca5de

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: flowguard-0.1.3-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 371.6 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.8.7

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 0e5ae8979ef7d4f598792a90b3cbbdacbdfe3920ed23f44936dd64fd202bcfc9
MD5 9dee619bc60b28b6f6df39e5a3fa85f0
BLAKE2b-256 c1a901362e5a4aa59eb0db7452ce45aa6658c4e37449478c2dc86a3f5b18dec2

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-win32.whl.

File metadata

  • Download URL: flowguard-0.1.3-cp38-abi3-win32.whl
  • Upload date:
  • Size: 340.4 kB
  • Tags: CPython 3.8+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.8.7

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-win32.whl
Algorithm Hash digest
SHA256 6a1085790c68867a8b25cbb2f357408e856d6c2a631ac2b776e88814503a1973
MD5 8046e5af88ef030f24aa4e8c1f24fe72
BLAKE2b-256 515a1cc3fab3979145f45dd0f9651e28aba4fb9cf9f33fa3280fd72491305f1d

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9470106c9614e1eec114554ebd43a67f3d2be78d71ea6442c4262cd06decf311
MD5 97bde4370c73cdeac4778f7b50f34595
BLAKE2b-256 dd205557f3cb3e9ea20999c8d5c9ed2d3329e446a710fb048dd588161f2550da

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 1544f69d5d9e47865167344305299086c2179ae23381d575e79ceacb376adbed
MD5 09d22baee77ccb6693fd0d3d484f3727
BLAKE2b-256 6ddfa2a17bb3412921799481b9f6c131871d6253fe82a36bb73d5fcf3d7fc7fc

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 83f6509d40f33dcc92c82416d2a43ca8c3b37761e6c656aa0c5505997d57c059
MD5 0d85fd00164da65974f989aad4bb45bb
BLAKE2b-256 442c24c37140d7e1fd188fd3e8791866b01658cbbf732602138e7ae1bae4e175

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d55d23200314b03ef25e66d94c37554b16a77ce4c195100353ca1aceadf2ad42
MD5 4604271b659e1b82783e5a844a710d87
BLAKE2b-256 2a4b0f1bd55feb9382ae180903b5ca7154dc41e76707e9d1af1eff52720f9556

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3af78b184aa4dd27cab4cd5fde05eac87f17d212a591b56e74a205fe193962d3
MD5 23e9a9f540429d52f8b26be6c2d2837d
BLAKE2b-256 66321a46b88ddba1acf5fcde29ad1261d8417c66012a6ccbc71ecf029ae94448

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 ab9707c7a0ebf067c04bc0069cf96b1ee5ec1b0a40e5058b1f7bb7f2355324bc
MD5 6d46e5ebd57189de9bb0ccc6b608c4a6
BLAKE2b-256 39590929e81cdfa58c45ad9cf84e52600a816e6ccf650ce49a12303f2fe1fc64

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 0e4a5e1e4d22718723dadc49429c3e0a345aa2ab4e13e9bdf38bd40b255835b4
MD5 b9a4a80ee9b54afe606268d2578fabf2
BLAKE2b-256 dc21867e0675e56de7acf96041c9e8185cd817cbdc91f1b37c6188a12d0f0f70

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 e7968a0c30eea2b0ba003013578e9b2eeae166da7a799d2d508c20a6cbcf0647
MD5 cbd9e821e90c4ec018ce548df5802034
BLAKE2b-256 919466d28734a4237fcab308edee5ee121adc3674a961869f6bd2cc3bccc2404

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 de3d1b03d26155e50e85aa8d732c02b202864c3bf00784d69970376f4abde607
MD5 3711eefcfbd94abebdab13436abafc0e
BLAKE2b-256 6715c97a344797c0434f8069bb30ded3b72493c1f9b06a81265204d9bcd1d562

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 8e68bb085f10f62616dcc2a0450e62392558acc0c05821635bd99b586b1677d8
MD5 743ded230bb49fe780057e8633775faa
BLAKE2b-256 55d0a5454ee112fd9416420adc43d69b52bf540f8e0747acf28accae2ad1fe19

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e5734ade930817bb88ea2e1002007de1504e44269d5d713d08fbfc2cf1045933
MD5 21d20ae5c2e31868ccff51fd801b1504
BLAKE2b-256 22515514bc1898053ce28205d848ecf9e51fb7391a6a06d54d15fa1ccfe95c9d

See more details on using hashes here.

File details

Details for the file flowguard-0.1.3-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for flowguard-0.1.3-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c1f4f738dd0321ba3471f6fff5c65ef47eb1b8cde3263ba5884daf8e25f5842a
MD5 56eecff8d1b6696154ba2ec144601fe9
BLAKE2b-256 f07a56c7abf72f42a7bc7a5b0481041631b2168c2a032786f9b0ceaea70cbe0a

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