Scheduler Setup¶
Imagine having a personal assistant who remembers to:
- Send birthday cards every year (cron job)
- Pay bills on the 1st of each month (scheduled task)
- Water your plants every Tuesday (recurring event)
- Remind you about meetings 10 minutes before (one-time task)
That's what the scheduler does for your application. It runs tasks automatically on a schedule, so you don't have to remember or manually trigger them. Your assistant never forgets, never sleeps, and works 24/7.
Configure and enable the built-in task scheduler in your Ravyn application using Asyncz.
What You'll Learn¶
- Installing scheduler support
- Enabling the scheduler
- Configuring AsynczConfig
- Registering tasks
- Best practices
Quick Start¶
from ravyn import Ravyn
from ravyn.contrib.schedulers.asyncz.config import AsynczConfig
app = Ravyn(
scheduler_config=AsynczConfig(),
enable_scheduler=True,
scheduler_tasks={
"daily_cleanup": "tasks.cleanup_old_data",
"hourly_sync": "tasks.sync_data"
}
)
Why Use the Scheduler?¶
-
Automated Tasks - Run jobs automatically
-
No Cron Needed - Built into your application
-
Asyncz Integration - Powerful scheduling library
-
Easy Configuration - Simple setup
Requirements¶
Install scheduler support:
pip install ravyn[schedulers]
This installs Asyncz, the scheduling library used by Ravyn.
AsynczConfig¶
The AsynczConfig class manages the scheduler integration with Asyncz.
Basic Configuration¶
from ravyn import Ravyn
from ravyn.contrib.schedulers.asyncz.config import AsynczConfig
app = Ravyn(
scheduler_config=AsynczConfig(),
enable_scheduler=True
)
Configuration Parameters¶
| Parameter | Type | Description | Default |
|---|---|---|---|
scheduler_class |
class | Asyncz scheduler type | AsyncIOScheduler |
tasks |
dict | Task name to path mapping | {} |
timezone |
str | Scheduler timezone | "UTC" |
configurations |
dict | Extra scheduler config | {} |
Enabling the Scheduler¶
The scheduler is disabled by default. Enable it with enable_scheduler=True.
Via Application¶
from ravyn import Ravyn
from ravyn.contrib.schedulers.asyncz.config import AsynczConfig
app = Ravyn(
scheduler_config=AsynczConfig(),
enable_scheduler=True # Required!
)
Via Settings¶
from ravyn import RavynSettings
from ravyn.contrib.schedulers.asyncz.config import AsynczConfig
class AppSettings(RavynSettings):
enable_scheduler: bool = True
scheduler_config: AsynczConfig = AsynczConfig()
app = Ravyn(settings_module=AppSettings)
Warning
Without enable_scheduler=True, the scheduler will not start!
Registering Tasks¶
Tasks must be registered with the application.
Task Registration¶
# tasks.py
from ravyn.contrib.schedulers.asyncz.decorator import scheduler
@scheduler(name="cleanup", trigger="cron", hour=2, minute=0)
async def cleanup_old_data():
"""Runs daily at 2 AM."""
await delete_old_records()
@scheduler(name="sync", trigger="interval", hours=1)
async def sync_data():
"""Runs every hour."""
await fetch_from_api()
Register in Application¶
# app.py
from ravyn import Ravyn
from ravyn.contrib.schedulers.asyncz.config import AsynczConfig
app = Ravyn(
scheduler_config=AsynczConfig(),
enable_scheduler=True,
scheduler_tasks={
"cleanup": "tasks.cleanup_old_data",
"sync": "tasks.sync_data"
}
)
Task mapping format: - Key - Task name (from @scheduler decorator) - Value - Import path to the task function
Complete Example¶
1. Create Tasks¶
# tasks.py
from ravyn.contrib.schedulers.asyncz.decorator import scheduler
@scheduler(name="daily_report", trigger="cron", hour=8, minute=0)
async def generate_daily_report():
"""Generate report at 8 AM daily."""
print("Generating daily report...")
await create_report()
@scheduler(name="data_sync", trigger="interval", minutes=30)
async def sync_external_data():
"""Sync data every 30 minutes."""
print("Syncing data...")
await fetch_data()
@scheduler(name="cleanup", trigger="cron", hour=2, minute=0)
async def cleanup_database():
"""Cleanup at 2 AM daily."""
print("Cleaning up...")
await delete_old_records()
2. Configure Application¶
# app.py
from ravyn import Ravyn
from ravyn.contrib.schedulers.asyncz.config import AsynczConfig
app = Ravyn(
scheduler_config=AsynczConfig(timezone="America/New_York"),
enable_scheduler=True,
scheduler_tasks={
"daily_report": "tasks.generate_daily_report",
"data_sync": "tasks.sync_external_data",
"cleanup": "tasks.cleanup_database"
}
)
3. Run Application¶
ravyn run
Tasks will run automatically according to their schedules!
Using Settings¶
Settings File¶
# settings.py
from ravyn import RavynSettings
from ravyn.contrib.schedulers.asyncz.config import AsynczConfig
class AppSettings(RavynSettings):
enable_scheduler: bool = True
scheduler_config: AsynczConfig = AsynczConfig(
timezone="UTC"
)
scheduler_tasks: dict = {
"daily_report": "tasks.generate_daily_report",
"data_sync": "tasks.sync_external_data",
"cleanup": "tasks.cleanup_database"
}
Application¶
# app.py
from ravyn import Ravyn
from settings import AppSettings
app = Ravyn(settings_module=AppSettings)
Run with Settings¶
# Linux/Mac
RAVYN_SETTINGS_MODULE=settings.AppSettings ravyn run
# Windows
$env:RAVYN_SETTINGS_MODULE="settings.AppSettings"; ravyn run
Advanced Configuration¶
Custom Stores and Executors¶
from ravyn import Ravyn
from ravyn.contrib.schedulers.asyncz.config import AsynczConfig
app = Ravyn(
scheduler_config=AsynczConfig(),
enable_scheduler=True,
scheduler_configurations={
"stores": {
"default": {"type": "memory"},
"redis": {
"type": "redis",
"host": "localhost",
"port": 6379
}
},
"executors": {
"default": {"type": "asyncio"},
"threadpool": {
"type": "threadpool",
"max_workers": 20
}
}
},
scheduler_tasks={
"task1": "tasks.my_task"
}
)
Using Custom Stores¶
# tasks.py
from ravyn.contrib.schedulers.asyncz.decorator import scheduler
@scheduler(
name="redis_task",
trigger="interval",
hours=1,
store="redis", # Use Redis store
executor="threadpool" # Use thread pool executor
)
async def task_with_redis():
await process_data()
Best Practices¶
1. Use Environment Variables¶
# Good - configurable
import os
class AppSettings(RavynSettings):
enable_scheduler: bool = os.getenv("ENABLE_SCHEDULER", "true") == "true"
scheduler_config: AsynczConfig = AsynczConfig(
timezone=os.getenv("TIMEZONE", "UTC")
)
2. Organize Tasks¶
app/
tasks/
__init__.py
cleanup.py
reports.py
sync.py
app.py
settings.py
3. Use Descriptive Task Names¶
# Good - clear names
scheduler_tasks = {
"user_cleanup_daily": "tasks.cleanup.cleanup_inactive_users",
"sales_report_weekly": "tasks.reports.generate_sales_report",
"api_sync_hourly": "tasks.sync.sync_with_external_api"
}
Common Pitfalls & Fixes¶
Pitfall 1: Scheduler Not Starting¶
Problem: Forgot to enable scheduler.
# Wrong - scheduler disabled
app = Ravyn(
scheduler_config=AsynczConfig()
# Missing enable_scheduler=True!
)
Solution: Enable the scheduler:
# Correct
app = Ravyn(
scheduler_config=AsynczConfig(),
enable_scheduler=True
)
Pitfall 2: Tasks Not Found¶
Problem: Wrong import path.
# Wrong - incorrect path
scheduler_tasks = {
"cleanup": "cleanup_old_data" # Missing module!
}
Solution: Use full import path:
# Correct
scheduler_tasks = {
"cleanup": "tasks.cleanup_old_data"
}
Pitfall 3: Timezone Issues¶
Problem: Tasks run at wrong times.
# Wrong - using default UTC
scheduler_config = AsynczConfig() # Defaults to UTC
Solution: Set correct timezone:
# Correct
scheduler_config = AsynczConfig(
timezone="America/New_York"
)
Scheduler Lifecycle¶
The scheduler integrates with Ravyn's lifecycle:
from ravyn import Ravyn
app = Ravyn(
scheduler_config=AsynczConfig(),
enable_scheduler=True
)
# Scheduler starts on application startup
# Scheduler stops on application shutdown
For custom lifecycle management, see Lifespan Events.
Learn More¶
- Asyncz Documentation - Complete scheduler reference
- Task Handlers - Create scheduled tasks
- SchedulerConfig - Configuration options
Next Steps¶
- Task Handlers - Create your first task
- Background Tasks - One-off tasks
- Lifespan Events - Application lifecycle