autocron api#
For the application API autocron provides the decorators cron and delay and the functions start(), stop() and get_results(). After importing autocron the decorators and function are accessible like i.e. autocron.start().
Functions decorated with delay will get executes later in a separate process. Functions decorated with cron will get executed periodically.
To start the autocron background workers, the function start() must get called somewere in the code. The function stop() will stop the workers. It is not necessary to call stop() because autocron stops the workers on shutdown of the main application (even on a kill 9).
start and stop#
To start the autocron background workers, call autocron.start(<filename>) with a database-filename as argument. The number of workers can be set by the admin-interface or given as an argument for autocron.start().
- class autocron.engine.Engine(interface=None)#
The Engine is the entry-point for autocron. Starting the engine will start the monitor process. The monitor-process in turn starts and supervises the workers. The monitor-process also checks whether the web-application itself is running. In case of an unexpected termination (or even a
kill 9), all worker processes will shut down gracefully - no orphaned processes or zombies left. (The interface argument is used for testing.)- start(database_file, workers=None)#
Starts the autocron workers in case autocron is active and no other application process has already started the workers. The
database_fileargument is a string with the name of the database to use (like “the_application.db”) or a Path instance. If the name represents a relative path, the database is stored in the~/.autocrondirectory. This directory will get created if not already existing. If the name represents an absolute path, then this path will be used as is. In this case all directories of the path must exist.The
workersargument takes the number of workers (as integer) and stores this value in the database. If the value isNone(default) the number of workers is taken from the database. Ifworkersis given, it will override and update the corresponding database setting.The function returns a boolean:
Trueif workers have been started andFalseotherwise. A return value ofFalsedoes not mean that no workers are running – another application process may have been first on aquiring the rights to start and monitor the worker processes.
- stop()#
Terminate the workers and tear-down the database. This method is called when the application itself terminates. It is not necessary to call this method directly.
cron#
A function decorated with cron should get never called from the application. Instead it will get called from autocron periodically. Because of this a cron-decorated function should not get arguments. The decorator can directly imported from autocron:
from autocron import cron
To register a cron-function (that means autocron is aware of the decorated function) the module where the function is defined must get imported from the application.
Implementation of the decorators cron and delay for running
recurring task and to delegate long running tasks to a background
process.
- autocron.decorators.cron(crontab=None, minutes=None, hours=None, days=None, months=None, days_of_week=None)
Decorator for a cronjob. Functions running cronjobs should not get called from the main program and therefore don’t get arguments. Example usage for a cronjob to run every hour, at the beginning of the hour:
>>> @cron("0 * * * *") >>> def some_callable(): >>> # do periodic stuff here ...
The decorator can take a couple of arguments but if just the first argument crontab is given then all other arguments are ignored. To use the other arguments instead, provide them all as keyword-arguments. If no arguments are given the default-crontab
(* * * * *)is used to execute a task every minute.- Crontab:
a string representing a valid crontab. See: https://en.wikipedia.org/wiki/Cron#CRON_expression with the restriction that only integers and the special signs (* , -) are allowed. Some examples
The order of arguments is: 'minutes hours dow months dom' '* * * * *': runs every minute (same as @periodic_task(seconds=60)) '15,30 7 * * *': runs every day at 7:15 and 7:30 '* 9 0 4,7 10-15': runs at 9:00 every monday and from the 10th to the 15th of a month but only in April and July.
- Minutes:
list of minutes during an hour when the task should run. Valid entries are integers in the range 0-59. Defaults to None which is the same as
*in a crontab, meaning that the task gets executed every minute.- Hours:
list of hours during a day when the task should run. Valid entries are integers in the range 0-23. Defaults to None which is the same as
*in a crontab, meaning that the task gets executed every hour.- Days:
list of days in an month the task should run. Valid entries are integers in the range 1-31. Defaults to None which is the same as
*in a crontab, meaning that the task gets executed every day.- Months:
list of month during a year when the task should run. Valid entries are integers in the range 1-12. Defaults to None which is the same as
*in a crontab, meaning that the task gets executed every month.- Days_of_week:
days of week. A list of integers from 0 to 6 with Monday as 0. The task runs only on the given weekdays. Defaults to None which is the same as
*in a crontab, meaning that the task gets executed every day of the week.
If neither days nor days_of_week are given, then the task will run every day of a month. If one of both is set, then the given restrictions apply. If both are set, then the allowed days complement each other.
Example#
Let’s consider a newsletter should get send on Monday and Wednesday at 9:30 am. This could be configured by means of a cron-string:
@cron("30 9 0,2 * *")
def send_newsletter():
...
and could also be configured by keyword-arguments:
@cron(minutes=[30], hours=[9], dow=[0, 2])
def send_newsletter():
...
delay#
To use the delay decorator autocron provides a shortcut for import:
from autocron import delay
Functions decorated with delay will return a Result instance (see below), wrapping the result. It is safe to ignore the return value. autocron will clean up the database from time to time to delete outdated results.
Implementation of the decorators cron and delay for running
recurring task and to delegate long running tasks to a background
process.
- autocron.decorators.delay(*args, weeks=0, days=0, hours=0, minutes=0, schedule=None)#
Decorator for a delayed task. Apply this as:
>>> @delay >>> def sendmail(recipient, message): >>> # code goes here ...
In this example decorator does not take any arguments. Calling
sendmail()will return from the call immediately and this callable will get executed later in another process.Optional the decorator can get called with arguments specifying a defined delay expressed in weeks, days, hours and minutes. In the next example the function
sendmail()will get executed in five minutes from now:>>> @delay(minutes=5) >>> def sendmail(recipient, message): >>> # code goes here ...
If
delayis called with arguments, all arguments must be keyword-arguments.If the argument
scheduleis given, this must be adatetimeobject. In this case all other keyword-arguments are ignored; the decorated function will get executed at the givenscheduleif the schedule is a date in the future. If thescheduleis in the past the function will get executed as soon as possibel.The decorated function will return a Result-instance. If autocron is active the result will be in waiting mode and may not be immediately in the database because the Result-dataset gets created in a separate thread. This dataset is updated with the result or error-message after function-execution.
If autocron is not active, the result-instance will be in ready- or error-mode, depending on the function call.
Result#
A delay-decorated function returns a Result instance. This is a wrapper around the delayed result. The instance provides the method is_ready() to indicate whether a task has been processed. The property has_error allows to check for errors – and in case of an error the attribute error_message holds the according error-message:
@delay
def do_this_later():
# code here ...
task_result = do_this_later()
...
if task_result.is_ready(): # note: this is a blocking call
if task_result.has_error:
# something went wrong
print(task_result.error_message)
else:
# the result is available:
result = task_result.result
else:
# try to get the result later
...
If autocron is inactive the decorated function will also return a Result instance with the return value of the function.
- class autocron.sqlite_interface.Result(connection=None, func=None, args=(), kwargs=None, function_result=None, error_message='', uuid='', status=1, ttl=None, function_name='', function_module='', function_arguments=None, rowid=None)#
The model to store function result of delayed executed tasks.
- property has_error#
Returns True if the error message is not empty. The return value is invalid as long as
is_ready()does not return True.
- is_ready()#
Returns
Trueif the task has been processed, otherwiseFalse. If the task has been processed the result may be available or an error-message may be set.Note for async frameworks: this is a blocking call.
- property result#
Shortcut for the attribute
function_result. The return value is invalid as long asis_ready()does not return True.