Skip to main content

Official Python SDK for Limitly - API Key management, plans, users and request validation

Project description

limitly-python

Official Python SDK for Limitly - API Key management, plans, users and request validation.

🚀 Installation

pip install limitly-python
poetry add limitly-python
pipenv install limitly-python

📖 Basic Usage

Initialization

from limitly import Limitly

limitly = Limitly(api_key="your_limitly_api_key")

Request Validation

The most common use case is validating your users' requests:

# Validate a request
result = await limitly.validation.validate(
    "user_api_key",
    "/api/users",
    "GET"
)

if result.success:
    print("Request allowed")
    print(f"Current usage: {result.details.current_usage}")
    print(f"Limit: {result.details.limit}")
else:
    print(f"Request denied: {result.error}")

API Key Management

# List all API Keys
keys = await limitly.api_keys.list()
print(f"API Keys: {keys.data}")

# Create a new API Key
new_key = await limitly.api_keys.create(
    name="New API Key",
    user_id=123
)
print(f"New API Key: {new_key.data.api_key}")

# Get usage for an API Key
usage = await limitly.api_keys.get_usage("key-id")
print(f"Usage: {usage.data}")

Plan Management

# Create a plan
plan = await limitly.plans.create(
    name="Basic Plan",
    description="Plan for basic users",
    max_requests=10000,
    request_period="month"
)

# Get plan usage statistics
plan_usage = await limitly.plans.get_usage(plan.data.id)
print(f"Plan usage: {plan_usage.data}")

User Management

# Create a user
user = await limitly.users.create(
    name="John Doe",
    email="john@example.com",
    plan_id="plan-id"
)

# Get user usage
user_usage = await limitly.users.get_usage(user.data.user_id)
print(f"User usage: {user_usage.data}")

🔧 Configuration

Configuration Options

from limitly import Limitly

limitly = Limitly(
    api_key="your_limitly_api_key",
    base_url="https://your-project.supabase.co/functions/v1",  # optional
    timeout=30  # optional, default: 30 seconds
)

Request Options

You can pass additional options to any method:

result = await limitly.api_keys.list(
    timeout=10,
    headers={"X-Custom-Header": "value"}
)

📚 Complete API

Request Validation

validation.validate(api_key, endpoint, method, options=None)

Validates a user request.

result = await limitly.validation.validate(
    "user_api_key",
    "/api/users",
    "GET"
)

validation.validate_request(data, options=None)

Validates a request with data object.

result = await limitly.validation.validate_request({
    "api_key": "user_api_key",
    "endpoint": "/api/users",
    "method": "GET"
})

API Keys

api_keys.list(options=None)

Lists all API Keys.

api_keys.create(data, options=None)

Creates a new API Key.

key = await limitly.api_keys.create({
    "name": "New API Key",
    "user_id": 123,  # optional
    "plan_id": "plan-id",  # optional
    "status": "active"  # optional
})

api_keys.get(key_id, options=None)

Gets a specific API Key.

api_keys.update(key_id, data, options=None)

Updates an API Key.

api_keys.delete(key_id, options=None)

Deletes an API Key (soft delete).

api_keys.regenerate(key_id, options=None)

Regenerates an API Key.

api_keys.get_usage(key_id, options=None)

Gets usage statistics for an API Key.

api_keys.get_requests(key_id, options=None)

Gets request history for an API Key.

Plans

plans.list(options=None)

Lists all plans.

plans.create(data, options=None)

Creates a new plan.

plan = await limitly.plans.create({
    "name": "Basic Plan",
    "description": "Plan for basic users",
    "max_requests": 10000,
    "request_period": "month",  # 'day', 'week', 'month', 'year'
    "is_active": True
})

plans.get(plan_id, options=None)

Gets a specific plan.

plans.update(plan_id, data, options=None)

Updates a plan.

plans.delete(plan_id, options=None)

Deletes a plan.

plans.get_usage(plan_id, options=None)

Gets usage statistics for a plan.

plans.get_users(plan_id, options=None)

Gets all users assigned to a plan.

plans.get_keys(plan_id, options=None)

Gets all API Keys assigned to a plan.

Users

users.list(options=None)

Lists all users.

users.create(data, options=None)

Creates a new user.

user = await limitly.users.create({
    "name": "John Doe",
    "email": "john@example.com",  # optional
    "plan_id": "plan-id",  # optional
    "custom_start": "2024-01-01T00:00:00.000Z"  # optional
})

users.get(user_id, options=None)

Gets a specific user.

users.update(user_id, data, options=None)

Updates a user.

users.delete(user_id, options=None)

Deletes a user.

users.get_usage(user_id, options=None)

Gets user usage.

users.get_keys(user_id, options=None)

Gets all API Keys for a user.

users.create_key(user_id, data, options=None)

Creates a new API Key for a user.

key = await limitly.users.create_key(123, {
    "name": "API Key for John"
})

🛠️ Error Handling

The SDK throws specific errors that you can catch:

from limitly import Limitly, LimitlyError

try:
    result = await limitly.validation.validate(
        "invalid_api_key",
        "/api/users",
        "GET"
    )
except LimitlyError as error:
    print(f"Limitly error: {error.message}")
    print(f"Status code: {error.status_code}")
    print(f"Full response: {error.response}")
except Exception as error:
    print(f"Unexpected error: {error}")

🔍 Advanced Examples

FastAPI Middleware

from fastapi import FastAPI, HTTPException, Request
from limitly import Limitly

app = FastAPI()
limitly = Limitly(api_key=os.getenv("LIMITLY_API_KEY"))

@app.middleware("http")
async def limitly_middleware(request: Request, call_next):
    api_key = request.headers.get("authorization", "").replace("Bearer ", "")
    
    if not api_key:
        raise HTTPException(status_code=401, detail="API Key required")
    
    try:
        result = await limitly.validation.validate(
            api_key,
            request.url.path,
            request.method
        )
        
        if not result.success:
            raise HTTPException(
                status_code=429,
                detail={
                    "error": "Rate limit exceeded",
                    "details": result.details
                }
            )
        
        response = await call_next(request)
        return response
    except LimitlyError as error:
        print(f"Validation error: {error}")
        raise HTTPException(status_code=500, detail="Internal error")

Usage Monitoring

# Monitor API Key usage
async def monitor_usage():
    keys = await limitly.api_keys.list()
    
    for key in keys.data or []:
        usage = await limitly.api_keys.get_usage(key.id)
        
        if usage.data and usage.data.percentage_used > 80:
            print(f"⚠️ API Key {key.name} is at {usage.data.percentage_used}% usage")

Automatic Plan Management

# Create predefined plans
async def setup_default_plans():
    plans = [
        {
            "name": "Basic Plan",
            "description": "For new users",
            "max_requests": 1000,
            "request_period": "month"
        },
        {
            "name": "Pro Plan",
            "description": "For advanced users",
            "max_requests": 10000,
            "request_period": "month"
        },
        {
            "name": "Enterprise Plan",
            "description": "Unlimited",
            "max_requests": -1,
            "request_period": "month"
        }
    ]
    
    for plan_data in plans:
        await limitly.plans.create(plan_data)

📦 Project Structure

src/limitly/
├── __init__.py          # Main SDK class
├── client.py            # Base HTTP client
├── types.py             # Type definitions
└── modules/             # Specific modules
    ├── __init__.py
    ├── api_keys.py
    ├── plans.py
    ├── users.py
    └── validation.py

🤝 Contributing

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License. See the LICENSE file for details.

🆘 Support

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

limitly_python-1.0.3.tar.gz (16.7 kB view details)

Uploaded Source

Built Distribution

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

limitly_python-1.0.3-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file limitly_python-1.0.3.tar.gz.

File metadata

  • Download URL: limitly_python-1.0.3.tar.gz
  • Upload date:
  • Size: 16.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.4

File hashes

Hashes for limitly_python-1.0.3.tar.gz
Algorithm Hash digest
SHA256 9cca0fdcb28854eee8b43af8a893be635470b06799da51a91b16e5dcf73c260e
MD5 028137827b108cdb24648943a5ffa620
BLAKE2b-256 b70bbb1dd35efd12a6e8d8fc0876f4201ff456d17f07444ea9eef60eadcdbf4f

See more details on using hashes here.

File details

Details for the file limitly_python-1.0.3-py3-none-any.whl.

File metadata

  • Download URL: limitly_python-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 15.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.4

File hashes

Hashes for limitly_python-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 03d12641daa3d6bb173735b6a2911227f4c6f42c7aba6cdcc5a2e87f6df1639c
MD5 30f3cf75e436c70bba6b02e80c60c401
BLAKE2b-256 fe7560196cccf0751874e71382cf65c0542ad3da97c5a48e5c3347675cc0515c

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