Official Python SDK for Limitly - API Key management, plans, users and request validation.
pip install limitly-pythonpoetry add limitly-pythonpipenv install limitly-pythonfrom limitly import Limitly
limitly = Limitly(api_key="your_limitly_api_key")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}")# 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}")# 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}")# 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}")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
)You can pass additional options to any method:
result = await limitly.api_keys.list(
timeout=10,
headers={"X-Custom-Header": "value"}
)Validates a user request.
result = await limitly.validation.validate(
"user_api_key",
"/api/users",
"GET"
)Validates a request with data object.
result = await limitly.validation.validate_request({
"api_key": "user_api_key",
"endpoint": "/api/users",
"method": "GET"
})Lists all API Keys.
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
})Gets a specific API Key.
Updates an API Key.
Deletes an API Key (soft delete).
Regenerates an API Key.
Gets usage statistics for an API Key.
Gets request history for an API Key.
Lists all plans.
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
})Gets a specific plan.
Updates a plan.
Deletes a plan.
Gets usage statistics for a plan.
Gets all users assigned to a plan.
Gets all API Keys assigned to a plan.
Lists all users.
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
})Gets a specific user.
Updates a user.
Deletes a user.
Gets user usage.
Gets all API Keys for a user.
Creates a new API Key for a user.
key = await limitly.users.create_key(123, {
"name": "API Key for John"
})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}")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")# 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")# 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)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
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License. See the LICENSE file for details.
- π§ Email: hi@limitly.dev
- π» Limitly: https://www.limitly.dev
- π Documentation: https://docs.limitly.com
- π Issues: https://github.com/limitlydev/limitly-python/issues