Complete guide to configuring Celery Throttle for your application.
- Overview
- Configuration Methods
- Configuration Options
- Redis Configuration
- Celery Configuration
- Environment Variables
- Configuration Examples
Celery Throttle uses pydantic-settings for configuration management, providing:
- ✅ Type validation
- ✅ Environment variable support with prefixes
- ✅ Nested configuration objects
- ✅ Multiple configuration methods
- ✅ Clear configuration precedence
Configuration is resolved in the following order (highest to lowest priority):
- Kwargs - Arguments passed directly to
CeleryThrottle() - Config Object - Explicit
CeleryThrottleConfiginstance - Environment Variables - Variables with
CELERY_THROTTLE_prefix - Default Values - Built-in defaults
The simplest approach - just set environment variables and initialize:
from celery_throttle import CeleryThrottle
# Loads configuration from environment variables
throttle = CeleryThrottle(celery_app=app)export CELERY_THROTTLE_REDIS_HOST=localhost
export CELERY_THROTTLE_REDIS_PORT=6379
export CELERY_THROTTLE_TARGET_QUEUE=my-queueQuick and convenient for small overrides:
from celery_throttle import CeleryThrottle
throttle = CeleryThrottle(
celery_app=app,
target_queue="custom-queue",
queue_prefix="myapp",
redis={"host": "redis.example.com", "port": 6379}
)Explicit and type-safe configuration:
from celery_throttle import CeleryThrottle
from celery_throttle.config import CeleryThrottleConfig, RedisConfig
config = CeleryThrottleConfig(
app_name="my-application",
target_queue="rate-limited-tasks",
queue_prefix="myapp",
redis=RedisConfig(
host="redis.example.com",
port=6379,
db=1,
password="secret"
)
)
throttle = CeleryThrottle(celery_app=app, config=config)Flexible configuration from dicts (useful for loading from files):
from celery_throttle import CeleryThrottle
config_dict = {
"app_name": "my-app",
"target_queue": "rate-limited-queue",
"queue_prefix": "myapp",
"redis": {
"host": "redis.example.com",
"port": 6379,
"db": 1
}
}
throttle = CeleryThrottle.from_config_dict(celery_app=app, config_dict=config_dict)Combine config object with kwargs overrides:
from celery_throttle import CeleryThrottle
from celery_throttle.config import CeleryThrottleConfig
# Base configuration
base_config = CeleryThrottleConfig(
app_name="my-app",
queue_prefix="production"
)
# Override specific settings
throttle = CeleryThrottle(
celery_app=app,
config=base_config,
target_queue="high-priority-queue" # Override
)| Option | Type | Default | Description |
|---|---|---|---|
app_name |
str |
"celery-throttle" |
Application name for logging and identification |
target_queue |
str |
"rate-limited-queue" |
Celery queue where rate-limited tasks are sent |
queue_prefix |
str |
"throttle" |
Redis key prefix for isolation (enables multi-service) |
redis |
RedisConfig |
See below | Redis connection configuration |
celery |
CeleryConfig |
See below | Celery application configuration |
| Option | Type | Default | Description |
|---|---|---|---|
host |
str |
"localhost" |
Redis server hostname |
port |
int |
6379 |
Redis server port |
db |
int |
0 |
Redis database number (0-15) |
password |
str |
None |
Redis password (optional) |
decode_responses |
bool |
False |
Whether to decode responses to strings |
Basic Redis:
from celery_throttle.config import RedisConfig
redis = RedisConfig(
host="localhost",
port=6379,
db=0
)Redis with Authentication:
redis = RedisConfig(
host="redis.example.com",
port=6380,
db=1,
password="my-secret-password"
)Redis Cluster/Sentinel:
# For advanced Redis setups, pass a custom client
import redis
redis_client = redis.RedisCluster(
host="cluster.example.com",
port=6379
)
throttle = CeleryThrottle(celery_app=app, redis_client=redis_client)| Option | Type | Default | Description |
|---|---|---|---|
broker_url |
str |
"redis://localhost:6379/0" |
Celery broker URL |
result_backend |
str |
"redis://localhost:6379/0" |
Celery result backend URL |
task_serializer |
str |
"json" |
Task serialization format |
accept_content |
list |
["json"] |
Accepted content types |
result_serializer |
str |
"json" |
Result serialization format |
timezone |
str |
"UTC" |
Timezone for scheduled tasks |
enable_utc |
bool |
True |
Enable UTC timezone |
worker_prefetch_multiplier |
int |
1 |
Worker prefetch multiplier |
task_acks_late |
bool |
True |
Acknowledge tasks after execution |
worker_concurrency |
int |
1 |
Number of concurrent worker processes |
Custom Celery Settings:
from celery_throttle.config import CeleryConfig
celery_config = CeleryConfig(
broker_url="redis://redis.example.com:6379/0",
result_backend="redis://redis.example.com:6379/1",
worker_concurrency=2,
timezone="America/New_York"
)Apply to Existing Celery App:
celery_config = CeleryConfig(
broker_url="redis://localhost:6379/0",
worker_concurrency=4
)
celery_config.apply_to_app(app)All configuration options can be set via environment variables with the CELERY_THROTTLE_ prefix.
export CELERY_THROTTLE_APP_NAME=my-app
export CELERY_THROTTLE_TARGET_QUEUE=rate-limited-tasks
export CELERY_THROTTLE_QUEUE_PREFIX=myappUse the CELERY_THROTTLE_REDIS_ prefix:
export CELERY_THROTTLE_REDIS_HOST=redis.example.com
export CELERY_THROTTLE_REDIS_PORT=6379
export CELERY_THROTTLE_REDIS_DB=1
export CELERY_THROTTLE_REDIS_PASSWORD=secret
export CELERY_THROTTLE_REDIS_DECODE_RESPONSES=falseUse the CELERY_THROTTLE_ prefix:
export CELERY_THROTTLE_BROKER_URL=redis://localhost:6379/0
export CELERY_THROTTLE_RESULT_BACKEND=redis://localhost:6379/1
export CELERY_THROTTLE_WORKER_CONCURRENCY=2
export CELERY_THROTTLE_WORKER_PREFETCH_MULTIPLIER=1
export CELERY_THROTTLE_TASK_ACKS_LATE=trueUse python-dotenv to load from .env files:
# .env file
CELERY_THROTTLE_REDIS_HOST=localhost
CELERY_THROTTLE_REDIS_PORT=6379
CELERY_THROTTLE_TARGET_QUEUE=my-queue
CELERY_THROTTLE_QUEUE_PREFIX=myappfrom dotenv import load_dotenv
from celery_throttle import CeleryThrottle
load_dotenv()
throttle = CeleryThrottle(celery_app=app)from celery_throttle import CeleryThrottle
from celery_throttle.config import CeleryThrottleConfig, RedisConfig
dev_config = CeleryThrottleConfig(
app_name="myapp-dev",
target_queue="dev-rate-limited",
queue_prefix="dev",
redis=RedisConfig(
host="localhost",
port=6379,
db=0
)
)
throttle = CeleryThrottle(celery_app=app, config=dev_config)from celery_throttle import CeleryThrottle
from celery_throttle.config import CeleryThrottleConfig, RedisConfig
prod_config = CeleryThrottleConfig(
app_name="myapp-prod",
target_queue="rate-limited-tasks",
queue_prefix="prod",
redis=RedisConfig(
host="redis-master.example.com",
port=6379,
db=1,
password=os.getenv("REDIS_PASSWORD")
)
)
throttle = CeleryThrottle(celery_app=app, config=prod_config)from celery_throttle import CeleryThrottle
from celery_throttle.config import CeleryThrottleConfig
def create_throttle_for_tenant(tenant_id: str):
config = CeleryThrottleConfig(
app_name=f"myapp-{tenant_id}",
target_queue=f"tenant-{tenant_id}-rate-limited",
queue_prefix=f"tenant_{tenant_id}"
)
return CeleryThrottle(celery_app=app, config=config)
# Each tenant gets isolated queues and Redis keys
tenant_a_throttle = create_throttle_for_tenant("tenant_a")
tenant_b_throttle = create_throttle_for_tenant("tenant_b")import fakeredis
from celery import Celery
from celery_throttle import CeleryThrottle
def create_test_throttle():
# Use fake Redis for testing
fake_redis = fakeredis.FakeRedis(decode_responses=False)
test_app = Celery('test-app')
return CeleryThrottle(
celery_app=test_app,
redis_client=fake_redis,
queue_prefix="test"
)
throttle = create_test_throttle()from celery_throttle import CeleryThrottle
from celery_throttle.config import CeleryThrottleConfig
# Service A - Email notifications
email_config = CeleryThrottleConfig(
app_name="email-service",
target_queue="email-rate-limited",
queue_prefix="email" # Redis keys: email:*
)
email_throttle = CeleryThrottle(celery_app=app, config=email_config)
# Service B - API calls
api_config = CeleryThrottleConfig(
app_name="api-service",
target_queue="api-rate-limited",
queue_prefix="api" # Redis keys: api:*
)
api_throttle = CeleryThrottle(celery_app=app, config=api_config)
# Services are completely isolatedAlways use unique queue_prefix values when running multiple services on the same Redis:
# ✅ Good - isolated
service_a = CeleryThrottle(celery_app=app, queue_prefix="service_a")
service_b = CeleryThrottle(celery_app=app, queue_prefix="service_b")
# ❌ Bad - will conflict
service_a = CeleryThrottle(celery_app=app, queue_prefix="throttle")
service_b = CeleryThrottle(celery_app=app, queue_prefix="throttle")Separate development, staging, and production:
# Development
dev_config = CeleryThrottleConfig(redis=RedisConfig(db=0))
# Staging
staging_config = CeleryThrottleConfig(redis=RedisConfig(db=1))
# Production
prod_config = CeleryThrottleConfig(redis=RedisConfig(db=2))Use environment variables for environment-specific settings:
import os
from celery_throttle import CeleryThrottle
# Load from environment (dev/staging/prod)
throttle = CeleryThrottle(
celery_app=app,
queue_prefix=os.getenv("ENVIRONMENT", "dev")
)Never hardcode passwords - use environment variables or secret managers:
# ✅ Good
config = CeleryThrottleConfig(
redis=RedisConfig(
password=os.getenv("REDIS_PASSWORD")
)
)
# ❌ Bad
config = CeleryThrottleConfig(
redis=RedisConfig(
password="hardcoded-secret" # Don't do this!
)
)Check your configuration after initialization:
throttle = CeleryThrottle(celery_app=app)
# Verify configuration
assert throttle.config.queue_prefix == "expected_prefix"
assert throttle.redis.ping() # Test Redis connectionProblem: Cannot connect to Redis
# Solution: Check Redis host and port
from celery_throttle.config import RedisConfig
redis_config = RedisConfig(host="localhost", port=6379)
redis_client = redis_config.create_client()
# Test connection
redis_client.ping() # Should return TrueProblem: Different services using same queue names
# Solution: Use unique queue prefixes
service_a = CeleryThrottle(celery_app=app, queue_prefix="service_a")
service_b = CeleryThrottle(celery_app=app, queue_prefix="service_b")Problem: Environment variables not being read
# Solution: Check prefix and load order
import os
# Verify environment variable exists
print(os.getenv("CELERY_THROTTLE_REDIS_HOST"))
# Load before initializing
throttle = CeleryThrottle(celery_app=app)
print(throttle.config.redis.host) # Should match env var- Main README - Getting started guide
- Examples - Comprehensive usage examples
- Pydantic Settings Documentation