twill-throttle


Nametwill-throttle JSON
Version 1.0.3 PyPI version JSON
download
home_pageNone
SummaryA Python rate limiter and throttling utility with async and sync support.
upload_time2025-08-10 15:13:08
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords throttle rate-limit async sync python utility
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
---

````markdown
# twill_throttle

A Python module providing **rate-limiting decorators** for synchronous and asynchronous functions.  
Includes two main classes:

- **`FuncPerMin`** – Limits the number of calls to a single function per minute.
- **`SharedRateLimiter`** – A shared rate limiter across multiple functions, supporting both sync and async.

---

## Features

- Per-function call limiting (`FuncPerMin`)
- Shared call limiting across multiple functions (`SharedRateLimiter`)
- Support for synchronous and asynchronous functions
- Sliding window rate limiting for precise control
- Thread-safe and async-safe locking
- Easy to integrate with any existing function or coroutine

---

## Installation

```bash
pip install twill_throttle
````

Or just copy the module file into your project.

---

## Usage

### Example 1 – Per-function limit

```python
from twill_throttle import FuncPerMin

@FuncPerMin(max_calls_per_minute=3)
def greet(name):
    print(f"Hello, {name}!")

for i in range(5):
    greet(f"User {i+1}")  # Last two calls will wait until the next minute
```

---

### Example 2 – Shared limit across multiple functions

```python
import asyncio
from twill_throttle import SharedRateLimiter

shared_limiter = SharedRateLimiter(max_calls_per_minute=4)

@shared_limiter
def process_data(data):
    print(f"Processing data: {data}")

@shared_limiter
async def async_task(task_id):
    print(f"Starting async task {task_id}...")
    await asyncio.sleep(0.5)
    print(f"Finished async task {task_id}.")

async def main():
    process_data("File1")
    process_data("File2")
    await asyncio.gather(
        async_task(1),
        async_task(2),
        async_task(3)
    )

asyncio.run(main())
```

---

## API Reference

### `FuncPerMin(max_calls_per_minute: int)`

Limits calls per minute for **one specific function**.

* **Parameters:**

  * `max_calls_per_minute` *(int)* – Maximum allowed calls per minute.
* **Behavior:**

  * Resets counter after 60 seconds from the first call.
  * If the limit is reached, blocks execution until the minute resets.

---

### `SharedRateLimiter(max_calls_per_minute: int)`

Limits calls per minute **shared** across multiple functions (sync & async).

* **Parameters:**

  * `max_calls_per_minute` *(int)* – Maximum allowed calls per minute.
* **Behavior:**

  * Uses a sliding time window for precision.
  * Waits until enough time passes before allowing a new call.
  * Works for both synchronous and asynchronous functions.

---

## Best Practices

* Use **`FuncPerMin`** when you only need to limit one specific function.
* Use **`SharedRateLimiter`** when multiple functions should share the same limit.
* Be aware that both limiters **block execution** until the limit resets.
  In async contexts, `SharedRateLimiter` will use non-blocking `asyncio.sleep()`.

---

## License

MIT License – You are free to use, modify, and distribute this code.

---







            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "twill-throttle",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "throttle, rate-limit, async, sync, python, utility",
    "author": null,
    "author_email": "Avi Twil <avitwil@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/b7/9b/029668af3c6eb1a077861d709715324d6e6b798d73dc54b621355e01b0e7/twill_throttle-1.0.3.tar.gz",
    "platform": null,
    "description": "\r\n---\r\n\r\n````markdown\r\n# twill_throttle\r\n\r\nA Python module providing **rate-limiting decorators** for synchronous and asynchronous functions.  \r\nIncludes two main classes:\r\n\r\n- **`FuncPerMin`** \u2013 Limits the number of calls to a single function per minute.\r\n- **`SharedRateLimiter`** \u2013 A shared rate limiter across multiple functions, supporting both sync and async.\r\n\r\n---\r\n\r\n## Features\r\n\r\n- Per-function call limiting (`FuncPerMin`)\r\n- Shared call limiting across multiple functions (`SharedRateLimiter`)\r\n- Support for synchronous and asynchronous functions\r\n- Sliding window rate limiting for precise control\r\n- Thread-safe and async-safe locking\r\n- Easy to integrate with any existing function or coroutine\r\n\r\n---\r\n\r\n## Installation\r\n\r\n```bash\r\npip install twill_throttle\r\n````\r\n\r\nOr just copy the module file into your project.\r\n\r\n---\r\n\r\n## Usage\r\n\r\n### Example 1 \u2013 Per-function limit\r\n\r\n```python\r\nfrom twill_throttle import FuncPerMin\r\n\r\n@FuncPerMin(max_calls_per_minute=3)\r\ndef greet(name):\r\n    print(f\"Hello, {name}!\")\r\n\r\nfor i in range(5):\r\n    greet(f\"User {i+1}\")  # Last two calls will wait until the next minute\r\n```\r\n\r\n---\r\n\r\n### Example 2 \u2013 Shared limit across multiple functions\r\n\r\n```python\r\nimport asyncio\r\nfrom twill_throttle import SharedRateLimiter\r\n\r\nshared_limiter = SharedRateLimiter(max_calls_per_minute=4)\r\n\r\n@shared_limiter\r\ndef process_data(data):\r\n    print(f\"Processing data: {data}\")\r\n\r\n@shared_limiter\r\nasync def async_task(task_id):\r\n    print(f\"Starting async task {task_id}...\")\r\n    await asyncio.sleep(0.5)\r\n    print(f\"Finished async task {task_id}.\")\r\n\r\nasync def main():\r\n    process_data(\"File1\")\r\n    process_data(\"File2\")\r\n    await asyncio.gather(\r\n        async_task(1),\r\n        async_task(2),\r\n        async_task(3)\r\n    )\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n---\r\n\r\n## API Reference\r\n\r\n### `FuncPerMin(max_calls_per_minute: int)`\r\n\r\nLimits calls per minute for **one specific function**.\r\n\r\n* **Parameters:**\r\n\r\n  * `max_calls_per_minute` *(int)* \u2013 Maximum allowed calls per minute.\r\n* **Behavior:**\r\n\r\n  * Resets counter after 60 seconds from the first call.\r\n  * If the limit is reached, blocks execution until the minute resets.\r\n\r\n---\r\n\r\n### `SharedRateLimiter(max_calls_per_minute: int)`\r\n\r\nLimits calls per minute **shared** across multiple functions (sync & async).\r\n\r\n* **Parameters:**\r\n\r\n  * `max_calls_per_minute` *(int)* \u2013 Maximum allowed calls per minute.\r\n* **Behavior:**\r\n\r\n  * Uses a sliding time window for precision.\r\n  * Waits until enough time passes before allowing a new call.\r\n  * Works for both synchronous and asynchronous functions.\r\n\r\n---\r\n\r\n## Best Practices\r\n\r\n* Use **`FuncPerMin`** when you only need to limit one specific function.\r\n* Use **`SharedRateLimiter`** when multiple functions should share the same limit.\r\n* Be aware that both limiters **block execution** until the limit resets.\r\n  In async contexts, `SharedRateLimiter` will use non-blocking `asyncio.sleep()`.\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT License \u2013 You are free to use, modify, and distribute this code.\r\n\r\n---\r\n\r\n\r\n\r\n\r\n\r\n\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Python rate limiter and throttling utility with async and sync support.",
    "version": "1.0.3",
    "project_urls": {
        "Bug Tracker": "https://github.com/avitwil/twill_throttle/issues",
        "Homepage": "https://github.com/avitwil/twill_throttle",
        "PyPI": "https://pypi.org/project/twill_throttle/"
    },
    "split_keywords": [
        "throttle",
        " rate-limit",
        " async",
        " sync",
        " python",
        " utility"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ca1d802a7e02b9c7b9c4ec058de6e3e0532736154599e63571fccfc0da1f6213",
                "md5": "8b5a574279cb6dbcac6cc1cfc7321286",
                "sha256": "61b5b0e32cb0618b298f9a4a0cdbe02a56e375454e5c5859bc898a476581c3cb"
            },
            "downloads": -1,
            "filename": "twill_throttle-1.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8b5a574279cb6dbcac6cc1cfc7321286",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 7852,
            "upload_time": "2025-08-10T15:13:06",
            "upload_time_iso_8601": "2025-08-10T15:13:06.143171Z",
            "url": "https://files.pythonhosted.org/packages/ca/1d/802a7e02b9c7b9c4ec058de6e3e0532736154599e63571fccfc0da1f6213/twill_throttle-1.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b79b029668af3c6eb1a077861d709715324d6e6b798d73dc54b621355e01b0e7",
                "md5": "7364cb983e31875485426fa2c69b4196",
                "sha256": "d6c961446f7c7a53f82e40e5d31943ace4d6fdad1b696d31023c53874ce48937"
            },
            "downloads": -1,
            "filename": "twill_throttle-1.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "7364cb983e31875485426fa2c69b4196",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 7311,
            "upload_time": "2025-08-10T15:13:08",
            "upload_time_iso_8601": "2025-08-10T15:13:08.333270Z",
            "url": "https://files.pythonhosted.org/packages/b7/9b/029668af3c6eb1a077861d709715324d6e6b798d73dc54b621355e01b0e7/twill_throttle-1.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-10 15:13:08",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "avitwil",
    "github_project": "twill_throttle",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "twill-throttle"
}
        
Elapsed time: 1.95511s