Skip to main content

Automatic OAuth credential rotation for CLI tools with quota limits

Project description

credential-rotation

Automatic OAuth credential rotation for CLI tools with quota limits.

Overview

This package provides automatic credential rotation for CLI tools that have usage quota limits. When a tool reports quota exhaustion, the system automatically switches to the next available account in a round-robin fashion.

Currently Supported:

  • Qwen CLI (qwen)

Planned Support:

  • OpenAI CLI
  • Anthropic Claude CLI
  • Generic pattern for any CLI tool

Installation

From PyPI (when published)

pip install credential-rotation

From GitHub

pip install git+https://github.com/dawid/credential-rotation.git

Development Install

git clone https://github.com/dawid/credential-rotation.git
cd credential-rotation
pip install -e ".[dev,qwen]"

Quick Start

1. Set Up Multiple Accounts

First, configure multiple Qwen accounts:

account-qwen --setup

This will guide you through:

  1. Opening a new terminal for each account (5 accounts recommended)
  2. Running qwen to initiate OAuth login
  3. Completing the browser authentication
  4. Saving credentials automatically

2. Use in Your Code

from credential_rotation import QwenWrapper

# Create wrapper with automatic rotation
wrapper = QwenWrapper(max_retries=5)

# Call with automatic fallback
result = wrapper.call_with_fallback(
    "Analyze this code",
    fallback_message="Analysis unavailable",
    timeout=45
)

if result:
    print(result)
else:
    print("All accounts exhausted")

3. Manual Account Management

# List all accounts with status
account-qwen --list

# Switch to specific account
account-qwen --switch 3

# Switch to next account (round-robin)
account-qwen --switch-next

# View usage statistics
account-qwen --stats

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                    Your Application                             │
└───────────────────────────┬─────────────────────────────────────┘
                            │ calls
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                      QwenWrapper                                │
│  • Executes CLI command                                        │
│  • Detects quota errors                                        │
│  • Calls AccountManager.switch_next() on quota error           │
│  • Retries with new account                                    │
└───────────────────────────┬─────────────────────────────────────┘
                            │ switches
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                      AccountManager                             │
│  • Atomic symlink update (os.replace)                          │
│  • File locking (fcntl.flock)                                  │
│  • State persistence (state.yaml)                              │
│  • Audit logging (rotation.log)                                │
└───────────────────────────┬─────────────────────────────────────┘
                            │ updates
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                    ~/.qwen/ structure                            │
│  ├── accounts/                                                  │
│  │   ├── oauth_creds_1.json                                   │
│  │   ├── oauth_creds_2.json                                   │
│  │   └── ...                                                   │
│  ├── oauth_creds.json → symlink to active account              │
│  ├── state.yaml                                                │
│  └── rotation.log                                              │
└─────────────────────────────────────────────────────────────────┘

Credential Storage

Credentials are stored in ~/.qwen/:

~/.qwen/
├── accounts/
│   ├── oauth_creds_1.json    # Account 1
│   ├── oauth_creds_2.json    # Account 2
│   ├── oauth_creds_3.json    # Account 3
│   ├── oauth_creds_4.json    # Account 4
│   └── oauth_creds_5.json    # Account 5
├── oauth_creds.json          # Symlink to current account
├── state.yaml                # Rotation state
└── rotation.log              # Audit log

API Reference

QwenWrapper

from credential_rotation import QwenWrapper

wrapper = QwenWrapper(max_retries=5)

# Basic call with automatic rotation
result = wrapper.call(prompt, timeout=45)

# Call with fallback message
output = wrapper.call_with_fallback(
    prompt,
    fallback_message="Fallback text",
    timeout=30
)

Returns:

  • WrapperResult(success=bool, output=str, error=str|None, attempts=int)

AccountManager

from credential_rotation import AccountManager

manager = AccountManager()

# Switch to specific account
manager.switch_to(3)

# Switch to next account (round-robin)
switched, next_index = manager.switch_next()

# List all accounts
accounts = manager.list_accounts()

# Get statistics
stats = manager.get_stats()

Testing

# Run tests
pytest

# Run with coverage
pytest --cov=credential_rotation --cov-report=html

Docker Usage

Mount the .qwen directory to share credentials:

services:
  app:
    image: your-app
    volumes:
      - ~/.qwen:/root/.qwen:ro

Security

  • Atomic Operations: Uses os.replace() for atomic symlink updates
  • File Locking: Uses fcntl.flock() to prevent concurrent modifications
  • Audit Trail: All switches logged to rotation.log
  • No Hardcoded Secrets: All credentials externalized to user directory

License

MIT License - see LICENSE file for details.

Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines.

Roadmap

  • OpenAI CLI support
  • Anthropic Claude CLI support
  • Per-account quota tracking
  • Configurable backoff strategies
  • Webhook notifications
  • Dashboard/monitoring UI

References

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

credential_rotation-0.1.0.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

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

credential_rotation-0.1.0-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

File details

Details for the file credential_rotation-0.1.0.tar.gz.

File metadata

  • Download URL: credential_rotation-0.1.0.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for credential_rotation-0.1.0.tar.gz
Algorithm Hash digest
SHA256 de3014f318cb9a91137b4995e5c75db6d89f5fc4de14176f2bd7e3fb1b08c144
MD5 bf2b72d57d61f54638d59b34f9bb1ccc
BLAKE2b-256 dc7a7e0d294f3f5dc09971e8cbffca27875a4a338b13f16a5b20daca064fc235

See more details on using hashes here.

File details

Details for the file credential_rotation-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for credential_rotation-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c93d0c37baa15a26830d3560690a2e9d16ae9e91f677d0b2cc2eb412856704d
MD5 9402937977e9b09e4bb364c48392b8c9
BLAKE2b-256 b48b47804460877237fb120923fb41be1453f756f76cf709dad3c95bbc44ca1f

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