Name | envrotate JSON |
Version |
0.1.1
JSON |
| download |
home_page | None |
Summary | Rotate environment variables (e.g., API keys) with cooldown intervals |
upload_time | 2025-10-22 12:39:34 |
maintainer | None |
docs_url | None |
author | Cauan |
requires_python | >=3.7 |
license | MIT |
keywords |
api
keys
rotation
env
environment-variables
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Env Rotator
Rotate API keys from environment variables with configurable cooldown intervals.
## Installation
```bash
pip install envrotate
```
## Usage
```python
import os
from envrotate import EnvRotate
# Set environment variables (in real use, set these externally)
os.environ["API_X_1"] = "key123"
os.environ["API_X_2"] = "key234"
os.environ["API_X_3"] = "key345"
# Initialize rotator
api_manager = EnvRotate(prefix="API_X_", min_interval=30)
# Get keys
print(api_manager.get(random=False, wait=True)) # "key123"
print(api_manager.get(random=True, wait=True)) # e.g., "key234"
print(api_manager.get(random=True, wait=True)) # e.g., "key345"
# After 30s cooldown, keys become available again
print(api_manager.get(random=True, wait=False)) # None (if <30s passed)
print(api_manager.get(random=True, wait=True)) # Waits then returns available key
```
## API Reference
### `EnvRotate(prefix: str, min_interval: int)`
Initializes the environment variable rotator.
- `prefix` (str): Environment variable prefix to match (e.g., "API_X_"). Only environment variables starting with this prefix will be included in the rotation.
- `min_interval` (int): Minimum seconds before a key can be reused. This sets the cooldown period between key usage.
**Raises:**
- `ValueError`: If no environment variables are found with the specified prefix.
### `get(random: bool = False, wait: bool = True) -> Optional[str]`
Retrieves an available key from the pool.
- `random` (bool, optional): If `True`, selects randomly from currently available keys. If `False` (default), uses round-robin selection starting with the key that became available earliest.
- `wait` (bool, optional): If `True` (default), blocks and waits until a key is available. If `False`, returns `None` immediately if no keys are available.
**Returns:**
- `str` or `None`: Returns an API key string when available. Returns `None` if `wait=False` and no keys are currently available.
## Features
- Thread-safe: Uses locks for concurrent access
- Flexible selection: Round-robin or random key selection
- Automatic waiting: Sleeps until next key is available when wait=True
- Environment-driven: Reads keys directly from os.environ
## Practical Example
```python
from envrotate import EnvRotate
import os
# In a real application, set these as actual environment variables
os.environ["OPENAI_API_KEY_1"] = "sk-123..."
os.environ["OPENAI_API_KEY_2"] = "sk-456..."
os.environ["OPENAI_API_KEY_3"] = "sk-789..."
# Initialize with 60-second cooldown between key reuse
rotator = EnvRotate(prefix="OPENAI_API_KEY_", min_interval=60)
# Use round-robin selection (first available key)
api_key = rotator.get(random=False, wait=True)
# Use random selection from available keys
api_key = rotator.get(random=True, wait=True)
# Don't wait if no keys available (returns None immediately)
api_key = rotator.get(random=False, wait=False)
if api_key:
# Use the key
pass
else:
# Handle no available keys
print("No keys currently available")
```
Raw data
{
"_id": null,
"home_page": null,
"name": "envrotate",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "api, keys, rotation, env, environment-variables",
"author": "Cauan",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/c8/92/d52fe449a5671592b7d15be1a834e407a50d953b13cf36325ea85968eddf/envrotate-0.1.1.tar.gz",
"platform": null,
"description": "# Env Rotator\n\nRotate API keys from environment variables with configurable cooldown intervals.\n\n## Installation\n```bash\npip install envrotate\n```\n\n## Usage\n```python\nimport os\nfrom envrotate import EnvRotate\n\n# Set environment variables (in real use, set these externally)\nos.environ[\"API_X_1\"] = \"key123\"\nos.environ[\"API_X_2\"] = \"key234\"\nos.environ[\"API_X_3\"] = \"key345\"\n\n# Initialize rotator\napi_manager = EnvRotate(prefix=\"API_X_\", min_interval=30)\n\n# Get keys\nprint(api_manager.get(random=False, wait=True)) # \"key123\"\nprint(api_manager.get(random=True, wait=True)) # e.g., \"key234\"\nprint(api_manager.get(random=True, wait=True)) # e.g., \"key345\"\n\n# After 30s cooldown, keys become available again\nprint(api_manager.get(random=True, wait=False)) # None (if <30s passed)\nprint(api_manager.get(random=True, wait=True)) # Waits then returns available key\n```\n\n## API Reference\n\n### `EnvRotate(prefix: str, min_interval: int)`\n\nInitializes the environment variable rotator.\n\n- `prefix` (str): Environment variable prefix to match (e.g., \"API_X_\"). Only environment variables starting with this prefix will be included in the rotation.\n- `min_interval` (int): Minimum seconds before a key can be reused. This sets the cooldown period between key usage.\n\n**Raises:**\n- `ValueError`: If no environment variables are found with the specified prefix.\n\n### `get(random: bool = False, wait: bool = True) -> Optional[str]`\n\nRetrieves an available key from the pool.\n\n- `random` (bool, optional): If `True`, selects randomly from currently available keys. If `False` (default), uses round-robin selection starting with the key that became available earliest.\n- `wait` (bool, optional): If `True` (default), blocks and waits until a key is available. If `False`, returns `None` immediately if no keys are available.\n\n**Returns:**\n- `str` or `None`: Returns an API key string when available. Returns `None` if `wait=False` and no keys are currently available.\n\n## Features\n- Thread-safe: Uses locks for concurrent access\n- Flexible selection: Round-robin or random key selection\n- Automatic waiting: Sleeps until next key is available when wait=True\n- Environment-driven: Reads keys directly from os.environ\n\n## Practical Example\n\n```python\nfrom envrotate import EnvRotate\nimport os\n\n# In a real application, set these as actual environment variables\nos.environ[\"OPENAI_API_KEY_1\"] = \"sk-123...\"\nos.environ[\"OPENAI_API_KEY_2\"] = \"sk-456...\"\nos.environ[\"OPENAI_API_KEY_3\"] = \"sk-789...\"\n\n# Initialize with 60-second cooldown between key reuse\nrotator = EnvRotate(prefix=\"OPENAI_API_KEY_\", min_interval=60)\n\n# Use round-robin selection (first available key)\napi_key = rotator.get(random=False, wait=True)\n\n# Use random selection from available keys\napi_key = rotator.get(random=True, wait=True)\n\n# Don't wait if no keys available (returns None immediately)\napi_key = rotator.get(random=False, wait=False)\nif api_key:\n # Use the key\n pass\nelse:\n # Handle no available keys\n print(\"No keys currently available\")\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Rotate environment variables (e.g., API keys) with cooldown intervals",
"version": "0.1.1",
"project_urls": {
"Homepage": "https://github.com/cauan/envrotate",
"Repository": "https://github.com/cauan/envrotate"
},
"split_keywords": [
"api",
" keys",
" rotation",
" env",
" environment-variables"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "d090ec1018ba18e04ae3136507d08f9aa905ba20d0fbc2db70e17e436fabc5b5",
"md5": "8abf50f104764a0d8276da33efd11a37",
"sha256": "dd5d5fef32e37008bf1297366d76047d2c30a5098a8272790a1a6a0a86c2c508"
},
"downloads": -1,
"filename": "envrotate-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8abf50f104764a0d8276da33efd11a37",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 3691,
"upload_time": "2025-10-22T12:39:32",
"upload_time_iso_8601": "2025-10-22T12:39:32.858524Z",
"url": "https://files.pythonhosted.org/packages/d0/90/ec1018ba18e04ae3136507d08f9aa905ba20d0fbc2db70e17e436fabc5b5/envrotate-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c892d52fe449a5671592b7d15be1a834e407a50d953b13cf36325ea85968eddf",
"md5": "6818406d944f0610d4b57bd426e1f186",
"sha256": "67f760bef631fc1acf7dc7f00adf39f03528f2ff6fb143aa35d3e99f562bb669"
},
"downloads": -1,
"filename": "envrotate-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "6818406d944f0610d4b57bd426e1f186",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 3728,
"upload_time": "2025-10-22T12:39:34",
"upload_time_iso_8601": "2025-10-22T12:39:34.574484Z",
"url": "https://files.pythonhosted.org/packages/c8/92/d52fe449a5671592b7d15be1a834e407a50d953b13cf36325ea85968eddf/envrotate-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-22 12:39:34",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cauan",
"github_project": "envrotate",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "envrotate"
}