Skip to main content

A package to run cron jobs(events)

Project description

Cron Events

This module provides a way to schedule recurring events using a cron-like syntax. Events can be scheduled to run at specific intervals or at specific times on specific days.

Table of Contents

Installation

pip install cronevents

Learn by Example

"""Cron-like event scheduling module.

This module provides a way to schedule recurring events using a cron-like syntax.
Events can be scheduled to run at specific intervals or at specific times on specific days.

Syntax:
    '(`every` | `in` | `on`) (`Weekday` | `n unit [n unit ...]`) [@ hh[:mm[:ss]] ["am" | "pm"]] [Timezone]'

    Combine multiple schedules with `||`:
    'every Monday @ 9:00 am || every Friday @ 5:00 pm'

Examples:
    'every 2 days @ 10:00:00 pm'
    'every Monday @ 23'
    'every 5 seconds'
    'every 2 days 1 hours 23 minutes 2 seconds'
    'every 1 days @ 9:00 am America/New_York'

Note:
    Using '@' will run the event at least once a day.
    Timezone defaults to UTC. Append any IANA timezone name (e.g. America/New_York)
    or a custom abbreviation registered with add_timezone_abbr().
"""

# Uncomment to register events to the event manager
# import os
# os.environ['REGISTER_CRON_EVENT'] = 'true'

from cronevents.event_manager import event, add_timezone_abbr


@event('every 31 seconds')
def test():
    """Write 'test' to a file and print it every 31 seconds."""
    with open('test.txt', 'a') as f:
        f.write('test\n')
    print('test')


@event('every 2 days 1 hours 23 minutes 2 seconds')
def test2():
    """Write 'test2' to a file and print 'test2' every 2 days, 1 hour, 23 minutes, and 2 seconds."""
    with open('test.txt', 'a') as f:
        f.write('test2\n')
    print('test2')


@event('every 1 days @ 2:00 pm')
def test3():
    """Write 'test3' to a file and print it daily at 2:00 PM."""
    with open('test.txt', 'a') as f:
        f.write('test3\n')
    print('test3')


@event('every Friday')
def test4():
    """Write 'test4' to a file and print it every Friday."""
    with open('test.txt', 'a') as f:
        f.write('test4\n')
    print('test4')


@event('every Tuesday @ 3:00')
def test5():
    """Write 'test5' to a file and print it every Tuesday at 3:00 AM."""
    with open('test.txt', 'a') as f:
        f.write('test5\n')
    print('test5')


# Use a full IANA timezone name appended to the query
@event('every 1 days @ 9:00 am America/New_York')
def test6():
    """Write 'test6' to a file and print it daily at 9:00 AM Eastern time."""
    with open('test.txt', 'a') as f:
        f.write('test6\n')
    print('test6')


# Or register a custom abbreviation and use that instead
add_timezone_abbr('America/Los_Angeles', 'PT')

@event('every Monday @ 8:00 am PT')
def test7():
    """Write 'test7' to a file and print it every Monday at 8:00 AM Pacific time."""
    with open('test.txt', 'a') as f:
        f.write('test7\n')
    print('test7')

Configuration

On first run, cronevents auto-creates a settings file at .cronevents/settings.yaml with the defaults shown below. Edit this file to change backends or toggle logging. The file location can be overridden with the CRONEVENTS_SETTINGS_PATH environment variable.

Default settings.yaml

log_cronevents_triggers: true   # record every time an event fires
log_cronevents_processes: false # capture stdout/stderr of event subprocesses

cronevents:                     # where registered events are stored
  module: cronevents.db.cronevents.sqlite
  name: Sqlite3CronEventsDb

logger:                         # how subprocess output is stored (when log_cronevents_processes: true)
  module: cronevents.db.logs.file
  name: FileLogger

trigger:                        # where trigger history is stored (when log_cronevents_triggers: true)
  module: cronevents.db.triggers.sqlite
  name: Sqlite3TriggerDb

How It Works

When anything imports from cronevents, get_settings() is called lazily on first use. It reads settings.yaml (or creates it if missing), then constructs a Settings object. Each of the three backend keys (cronevents, logger, trigger) is a module/name pair pointing to a class that cronevents will import and instantiate at runtime. If the class can't be loaded for any reason, it falls back to the SQLite/file defaults.

Using PostgreSQL Backends

Switch any or all backends to Postgres by updating settings.yaml:

log_cronevents_triggers: true
log_cronevents_processes: true

cronevents:
  module: cronevents.db.cronevents.postgres
  name: PostgresCronEventsDb

logger:
  module: cronevents.db.logs.postgres
  name: PostgresLogger

trigger:
  module: cronevents.db.triggers.postgres
  name: PostgresTriggerDb

The Postgres backends read connection details from environment variables (or a .env file):

Variable Default
POSTGRES_HOST localhost
POSTGRES_PORT 5432
POSTGRES_USER
POSTGRES_PASSWORD
POSTGRES_DATABASE

Custom Backends

You can point any backend at your own class — just subclass the appropriate base and reference it in settings.yaml.

Custom event store — subclass CronEventsDbBase:

# myproject/my_store.py
from cronevents.db.cronevents.base import CronEventsDbBase, CronEvent

class MyCronEventsDb(CronEventsDbBase):
    def insert(self, cronevent: CronEvent) -> None: ...
    def update(self, cronevent: CronEvent) -> None: ...
    def upsert(self, cronevent: CronEvent) -> None: ...
    def delete(self, cronevent_id: str) -> None: ...
    def get(self, cronevent_id=None, module=None, func=None) -> CronEvent | None: ...
    def list(self) -> list[CronEvent]: ...

Custom logger — subclass LoggerBase:

# myproject/my_logger.py
from cronevents.db.logs.base import LoggerBase, Log

class MyLogger(LoggerBase):
    def __init__(self, trigger_id: str): ...
    def log(self, log: str): ...
    def __exit__(self, exc_type, exc_val, exc_tb): ...
    def list(self, stream: bool = False) -> list[Log]: ...

Custom trigger store — subclass TriggerDbBase:

# myproject/my_triggers.py
from cronevents.db.triggers.base import TriggerDbBase, Trigger

class MyTriggerDb(TriggerDbBase):
    def insert(self, trigger: Trigger): ...
    def upsert(self, trigger: Trigger): ...
    def list(self, stream=False, cronevent_id=None) -> list[Trigger]: ...

Then reference your class in settings.yaml:

cronevents:
  module: myproject.my_store
  name: MyCronEventsDb

logger:
  module: myproject.my_logger
  name: MyLogger

trigger:
  module: myproject.my_triggers
  name: MyTriggerDb

Environment Variables

Variable Default Description
CRONEVENTS_SETTINGS_PATH .cronevents/settings.yaml Path to the settings file
CRONEVENTS_LOG_DIR .cronevents/logs Directory for file-based process logs
REGISTER_CRON_EVENT false Set to true to register events on import
POSTGRES_HOST localhost Postgres host (Postgres backends only)
POSTGRES_PORT 5432 Postgres port
POSTGRES_USER Postgres user
POSTGRES_PASSWORD Postgres password
POSTGRES_DATABASE Postgres database name

License

  • MIT License

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cronevents-0.0.44.tar.gz (37.8 kB view details)

Uploaded Source

Built Distribution

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

cronevents-0.0.44-py3-none-any.whl (46.9 kB view details)

Uploaded Python 3

File details

Details for the file cronevents-0.0.44.tar.gz.

File metadata

  • Download URL: cronevents-0.0.44.tar.gz
  • Upload date:
  • Size: 37.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for cronevents-0.0.44.tar.gz
Algorithm Hash digest
SHA256 cb02d51353640098f4042710d22debfab3ccb692cde7e107362b8d4fed445a8a
MD5 7b0c076275eb2cbacdf45af9f12f25aa
BLAKE2b-256 3dd3ccee9e9e1787db5a2a938586e4d91c3ec58744abd12f2c9177ea8d7fd17e

See more details on using hashes here.

File details

Details for the file cronevents-0.0.44-py3-none-any.whl.

File metadata

  • Download URL: cronevents-0.0.44-py3-none-any.whl
  • Upload date:
  • Size: 46.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for cronevents-0.0.44-py3-none-any.whl
Algorithm Hash digest
SHA256 d2a4855ab7e592f24eae6c723be7c886ac5d89a30fea0ab75e43d3ab82e7850f
MD5 cd0f3c8dc687bd083cfb4ed6f1547995
BLAKE2b-256 b82225ccae394ec8515cbf1d08d500ce98bd2a8237a402d7483c25a3443cb7fe

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