Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.limitly.dev/llms.txt

Use this file to discover all available pages before exploring further.

The Limitly Python SDK provides powerful request validation capabilities to enforce rate limits and usage policies.

Basic Validation

Validate a request using the user’s API key:
from limitly import Limitly

limitly = Limitly(api_key="your_limitly_api_key")

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

if result.success:
    print("Request allowed")
else:
    print(f"Request denied: {result.error}")

FastAPI Integration

Integrate validation directly into your FastAPI application:
from fastapi import FastAPI, HTTPException, Depends
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from limitly import Limitly

app = FastAPI()
security = HTTPBearer()

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

async def validate_request(credentials: HTTPAuthorizationCredentials = Depends(security)):
    api_key = credentials.credentials
    
    result = limitly.validation.validate(api_key, "/api/users", "GET")
    
    if not result.success:
        raise HTTPException(
            status_code=429, 
            detail={
                "error": "Rate limit exceeded",
                "details": result.details
            }
        )
    
    return api_key

@app.get("/api/users")
async def get_users(api_key: str = Depends(validate_request)):
    return {"message": "Users retrieved successfully"}

Flask Integration

Integrate validation into your Flask application:
from flask import Flask, request, jsonify
from limitly import Limitly

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

@app.route("/api/users", methods=["GET"])
def get_users():
    api_key = request.headers.get("Authorization", "").replace("Bearer ", "")
    
    if not api_key:
        return jsonify({"error": "API Key required"}), 401
    
    result = limitly.validation.validate(api_key, request.path, request.method)
    
    if not result.success:
        return jsonify({
            "error": "Rate limit exceeded",
            "details": result.details
        }), 429
    
    return jsonify({"message": "Users retrieved successfully"})

Django Integration

Integrate validation into your Django application:
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from limitly import Limitly

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

@csrf_exempt
def get_users(request):
    api_key = request.headers.get("Authorization", "").replace("Bearer ", "")
    
    if not api_key:
        return JsonResponse({"error": "API Key required"}, status=401)
    
    result = limitly.validation.validate(api_key, request.path, request.method)
    
    if not result.success:
        return JsonResponse({
            "error": "Rate limit exceeded",
            "details": result.details
        }, status=429)
    
    return JsonResponse({"message": "Users retrieved successfully"})

Validation Response

The validation method returns a detailed response:
from limitly import ValidateRequestResponse

def validate_user_request(api_key: str, path: str, method: str) -> ValidateRequestResponse:
    return limitly.validation.validate(api_key, path, method)

# The response includes:
# - success: bool
# - error: Optional[str]
# - details: Optional[dict] with limit, remaining, reset, retryAfter

Custom Validation Options

You can pass additional options to the validation:
result = limitly.validation.validate(
    "user_api_key",
    "/api/users",
    "GET",
    options={
        "timeout": 5,
        "retry_attempts": 3
    }
)

Error Handling

Handle different types of validation errors:
from limitly import Limitly, LimitlyError

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

try:
    result = limitly.validation.validate("user_api_key", "/api/users", "GET")
    
    if result.success:
        print("Request allowed")
        print(f"Remaining requests: {result.details.remaining}")
    else:
        print(f"Request denied: {result.error}")
        if result.details:
            print(f"Retry after: {result.details.retryAfter} seconds")
            
except LimitlyError as e:
    print(f"Validation error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")

Middleware Pattern

Create reusable validation middleware:
from functools import wraps
from flask import request, jsonify

def rate_limit_middleware(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        api_key = request.headers.get("Authorization", "").replace("Bearer ", "")
        
        if not api_key:
            return jsonify({"error": "API Key required"}), 401
        
        result = limitly.validation.validate(api_key, request.path, request.method)
        
        if not result.success:
            return jsonify({
                "error": "Rate limit exceeded",
                "details": result.details
            }), 429
        
        return f(*args, **kwargs)
    return decorated_function

# Use the middleware
@app.route("/api/users", methods=["GET"])
@rate_limit_middleware
def get_users():
    return jsonify({"message": "Users retrieved successfully"})

Async Validation

For async applications, you can use async validation:
import asyncio
from limitly import Limitly

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

async def validate_request_async(api_key: str, path: str, method: str):
    # Note: This is a simplified example
    # In practice, you'd want to handle the async validation properly
    result = limitly.validation.validate(api_key, path, method)
    return result

async def handle_request():
    result = await validate_request_async("user_api_key", "/api/users", "GET")
    return result

Testing Validation

Test your validation setup:
import os
from limitly import Limitly

def test_validation():
    limitly = Limitly(api_key=os.getenv("LIMITLY_API_KEY"))
    
    # Test valid request
    result = limitly.validation.validate("valid_api_key", "/api/test", "GET")
    print(f"Valid request: {result.success}")
    
    # Test rate limit exceeded
    for i in range(100):  # Make many requests
        result = limitly.validation.validate("limited_api_key", "/api/test", "GET")
        if not result.success:
            print(f"Rate limit hit after {i+1} requests")
            break

if __name__ == "__main__":
    test_validation()

CLI Validation

Test validation using the CLI tool:
# Test request validation
limitly validate --api-key user_key --path /api/users --method GET

# Test with custom options
limitly validate --api-key user_key --path /api/users --method POST --timeout 10

Error Types

The SDK handles various error scenarios:
  • Invalid API Key: Returns authentication error
  • Rate Limit Exceeded: Returns rate limit error with details
  • Network Errors: Returns connection error
  • Validation Errors: Returns validation error

Next Steps