---
````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"
}