Metadata-Version: 2.4
Name: lightrate-client
Version: 1.0.0
Summary: Python client for the Lightrate API
Home-page: https://github.com/lightbourne-technologies/lightrate-client-python
Author: Lightbourne Technologies
Author-email: grayden@lightbournetechnologies.ca
Project-URL: Homepage, https://github.com/lightbourne-technologies/lightrate-client-python
Project-URL: Issues, https://github.com/lightbourne-technologies/lightrate-client-python/issues
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: flake8>=5.0.0; extra == "dev"
Requires-Dist: mypy>=0.991; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# LightRate Client Python

A Python client for the Lightrate token management API, providing easy-to-use methods for consuming tokens with local bucket management.

## Installation

```bash
pip install lightrate-client
```

## Usage

### Configuration

Configure the client with your API credentials:

```python
from lightrate_client import configure, get_client

configure(
    api_key='your_api_key',
    application_id='your_application_id',  # required
    timeout=30,  # optional, defaults to 30 seconds
    retry_attempts=3,  # optional, defaults to 3
    default_local_bucket_size=5  # optional, defaults to 5
)
```

### Basic Usage

```python
from lightrate_client import LightRateClient, create_client

# Simple usage - pass your API key and application ID
client = LightRateClient('your_api_key', 'your_application_id')

# Or use the convenience method
client = create_client('your_api_key', 'your_application_id')

# With additional options
client = LightRateClient('your_api_key', 'your_application_id', ClientOptions(
    timeout=60,
    default_local_bucket_size=10
))

# Or configure globally and use the default client
configure(api_key='your_api_key', application_id='your_application_id')
client = get_client()
```

### Consuming Tokens

```python
# Consume tokens by operation
response = client.consume_tokens(
    user_identifier='user123',
    tokens_requested=1,
    operation='send_email'
)

# Or consume tokens by path
response = client.consume_tokens(
    user_identifier='user123',
    tokens_requested=1,
    path='/api/v1/emails/send',
    http_method='POST'
)

if response.tokens_consumed > 0:
    print(f"Tokens consumed successfully. Remaining: {response.tokens_remaining}")
else:
    print(f"Failed to consume tokens")
```

#### Using Local Token Buckets

The client supports local token buckets for improved performance. Buckets are automatically created based on the rules returned by the API, and are matched against incoming requests using the `matcher` field from the rule.

```python
# Configure client with default bucket size
client = LightRateClient('your_api_key', 'your_application_id', ClientOptions(
    default_local_bucket_size=20  # All operations use this bucket size
))

# Consume tokens using local bucket (more efficient)
result = client.consume_local_bucket_token(
    user_identifier='user123',
    operation='send_email'
)

print(f"Success: {result.success}")
print(f"Used local token: {result.used_local_token}")
print(f"Bucket status: {result.bucket_status}")
```

**Bucket Matching:**
- Buckets are matched using the `matcher` field from the rule, which supports regex patterns
- Each user has separate buckets per rule, ensuring proper isolation
- Buckets expire after 60 seconds of inactivity
- Default rules (isDefault: true) do not create local buckets

### Complete Example

```python
from lightrate_client import LightRateClient

# Create a client with your API key and application ID
client = LightRateClient('your_api_key', 'your_application_id')

try:
    # Consume tokens
    consume_response = client.consume_tokens(
        user_identifier='user123',
        tokens_requested=1,
        operation='send_email'
    )

    if consume_response.tokens_consumed > 0:
        print(f"Successfully consumed tokens. Remaining: {consume_response.tokens_remaining}")
        # Proceed with your operation
    else:
        print("Failed to consume tokens")
        # Handle rate limiting

except UnauthorizedError as e:
    print(f"Authentication failed: {e}")
except TooManyRequestsError as e:
    print(f"Rate limited: {e}")
except APIError as e:
    print(f"API Error ({e.status_code}): {e}")
except NetworkError as e:
    print(f"Network error: {e}")
```

## Error Handling

The client provides comprehensive error handling with specific exception types:

```python
from lightrate_client import (
    UnauthorizedError,
    NotFoundError,
    APIError,
    NetworkError,
    TimeoutError
)

try:
    response = client.consume_tokens(...)
except UnauthorizedError as e:
    print(f"Authentication failed: {e}")
except NotFoundError as e:
    print(f"Resource not found: {e}")
except APIError as e:
    print(f"API Error ({e.status_code}): {e}")
except NetworkError as e:
    print(f"Network error: {e}")
except TimeoutError as e:
    print(f"Request timed out: {e}")
```

Available error types:
- `LightRateError` - Base error class
- `ConfigurationError` - Configuration-related errors
- `AuthenticationError` - Authentication-related errors
- `APIError` - Base API error class
- `BadRequestError` - 400 errors
- `UnauthorizedError` - 401 errors
- `ForbiddenError` - 403 errors
- `NotFoundError` - 404 errors
- `UnprocessableEntityError` - 422 errors
- `TooManyRequestsError` - 429 errors
- `InternalServerError` - 500 errors
- `ServiceUnavailableError` - 503 errors
- `NetworkError` - Network-related errors
- `TimeoutError` - Request timeout errors

## API Reference

### Classes

#### `LightRateClient`

Main client class for interacting with the LightRate API.

**Constructor:**
```python
LightRateClient(api_key: str, application_id: str, options: Optional[ClientOptions] = None)
```

**Methods:**

- `consume_tokens(user_identifier, tokens_requested, operation=None, path=None, http_method=None) -> ConsumeTokensResponse`
- `consume_local_bucket_token(user_identifier, operation=None, path=None, http_method=None) -> ConsumeLocalBucketTokenResponse`
- `consume_tokens_with_request(request) -> ConsumeTokensResponse`
- `get_all_bucket_statuses() -> Dict[str, Any]`
- `reset_all_buckets() -> None`
- `get_configuration() -> Configuration`

#### `Configuration`

Configuration class for client settings.

**Methods:**
- `is_valid() -> bool`
- `to_dict() -> Dict[str, Any]`
- `update(**options) -> None`

### Global Functions

- `configure(**options) -> None` - Configure global client
- `get_client() -> LightRateClient` - Get global client instance
- `create_client(api_key, application_id, **options) -> LightRateClient` - Create new client
- `reset() -> None` - Reset global configuration

## Development

After checking out the repo, run `pip install -e .[dev]` to install dependencies. Then, run `pytest` to run the tests.

To build the project, run `python setup.py sdist bdist_wheel`.

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/lightbourne-technologies/lightrate-client-python. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

## License

The package is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
