summaryrefslogtreecommitdiff
path: root/docs/index.rst
blob: e0ef87c569fa7f8bea2e94dd0a54e70575c36dea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
Advanced Python Scheduler
=========================

Advanced Python Scheduler (APScheduler) is a light but powerful in-process task
scheduler that lets you schedule functions (or any other python callables) to be
executed at times of your choosing.

This can be a far better alternative to externally run cron scripts for
long-running applications (e.g. web applications), as it is platform neutral
and can directly access your application's variables and functions.

The development of APScheduler was heavily influenced by the `Quartz
<http://www.quartz-scheduler.org/>`_ task scheduler written in Java.
APScheduler provides most of the major features that Quartz does, but it also
provides features not present in Quartz (such as multiple job stores).


Features
--------

* No (hard) external dependencies
* Thread-safe API
* Excellent test coverage (tested on Python 2.4 - 2.7, 3.1 - 3.2, Jython 2.5.2 and PyPy 1.4.1)
* Configurable scheduling mechanisms (triggers):

  * Cron-like scheduling
  * Delayed scheduling of single run jobs (like the UNIX "at" command)
  * Interval-based (run a job at specified time intervals)
* Persistent, stateful jobs
* Multiple, simultaneously active job stores:

  * RAM 
  * File-based simple database (shelve)
  * `SQLAlchemy <http://www.sqlalchemy.org/>`_ (any supported RDBMS works)
  * `MongoDB <http://www.mongodb.org/>`_


Usage
=====

Installing APScheduler
----------------------

The preferred method of installation is with
`pip <http://pypi.python.org/pypi/pip/>`_ or
`easy_install <http://pypi.python.org/pypi/distribute/>`_::

    $ pip install apscheduler

or::

	$ easy_install apscheduler

If that doesn't work, you can manually `download the APScheduler package
<http://pypi.python.org/pypi/APScheduler/>`_ from PyPI, extract and then
install it::

    $ python setup.py install


Starting the scheduler
----------------------

To start the scheduler with default settings::

    from apscheduler.scheduler import Scheduler
    
    sched = Scheduler()
    sched.start()

The constructor takes as its first, optional parameter a dictionary of "global"
options to facilitate configuration from .ini files. All APScheduler options
given in the global configuration must begin with "apscheduler." to avoid name
clashes with other software. The constructor also takes options as keyword
arguments (without the prefix).

You can also configure the scheduler after its instantiation, if necessary.
This is handy if you use the decorators for scheduling and must have a
Scheduler instance available from the very beginning::

    from apscheduler.scheduler import Scheduler
    
    sched = Scheduler()
    
    @sched.interval_schedule(hours=3)
    def some_job():
        print "Decorated job"
    
    sched.configure(options_from_ini_file)
    sched.start()


Scheduling jobs
---------------

The simplest way to schedule jobs using the built-in triggers is to use one of
the shortcut methods provided by the scheduler:

.. toctree::
   :maxdepth: 1

   dateschedule
   intervalschedule
   cronschedule

These shortcuts cover the vast majority of use cases. However, if you need
to use a custom trigger, you need to use the
:meth:`~apscheduler.scheduler.Scheduler.add_job` method.

When a scheduled job is triggered, it is handed over to the thread pool for
execution.

You can request a job to be added to a specific job store by giving the target
job store's alias in the ``jobstore`` option to
:meth:`~apscheduler.scheduler.Scheduler.add_job` or any of the above shortcut
methods.

You can schedule jobs on the scheduler **at any time**. If the scheduler is not
running when the job is added, the job will be scheduled `tentatively` and its
first run time will only be computed when the scheduler starts. Jobs will not
run retroactively in such cases.


Shutting down the scheduler
---------------------------

::

    sched.shutdown()

A scheduler that has been shut down can be restarted, but the shutdown
procedure clears any scheduled non-persistent jobs.

If you want to make sure that the scheduler has really terminated, you
can specify a timeout (in seconds)::

    sched.shutdown(10)

This will wait at most 10 seconds for the scheduler thread to terminate,
and then proceed anyways.

To make sure that the scheduler has terminated, you can specify
a timeout of 0. This will disable the waiting timeout and will wait as long as
it takes for the scheduler to shut down.

.. note::
	Shutting down the scheduler does not guarantee that all jobs have
	terminated.


Scheduler configuration options
-------------------------------

======================= ======== ==============================================
Directive               Default  Definition
======================= ======== ==============================================
misfire_grace_time      1        Maximum time in seconds for the job execution
                                 to be allowed to delay before it is considered
                                 a misfire
coalesce                False    Roll several pending executions of jobs into one
daemonic                True     Controls whether the scheduler thread is
                                 daemonic or not.
                                 
                                 If set to ``False``, then the
                                 scheduler must be shut down explicitly
                                 when the program is about to finish, or it will
                                 prevent the program from terminating.

                                 If set to ``True``, the scheduler will
                                 automatically terminate with the application,
                                 but may cause an exception to be raised on
                                 exit.
                                 
                                 Jobs are always executed in non-daemonic
                                 threads.
threadpool                       
threadpool.core_threads 0        Maximum number of persistent threads in the pool
threadpool.max_threads  None     Maximum number of total threads in the pool
threadpool.keepalive    1        Seconds to keep non-core worker threads waiting
                                 for new tasks
jobstores.X.class                Class of the jobstore named X (specified as
                                 module.name:classname)
jobstores.X.Y                    Constructor option Y of jobstore X
======================= ======== ==============================================


Job stores
----------

APScheduler keeps all the scheduled jobs in `job stores`. Job stores are
configurable adapters to some back-end that may or may not support persisting
job configurations on disk, database or something else. Job stores are added
to the scheduler and identified by their aliases. The alias "default" is special
in that if the user does not explicitly specify a job store alias when scheduling
a job, it goes to the "default" job store. If there is no job store in the
scheduler by that name when the scheduler is started, a new job store of type
:class:`~apscheduler.jobstores.ram_store.RAMJobStore` is created to serve as
the default.

Job stores can be added either through configuration options or the
:meth:`~apscheduler.scheduler.Scheduler.add_jobstore` method. The following
are therefore equal::

    config = {'apscheduler.jobstores.file.class': 'apscheduler.jobstores.shelve_store:ShelveJobStore',
              'apscheduler.jobstores.file.path': '/tmp/dbfile'}
    sched = Scheduler(config)

and::

    from apscheduler.jobstores.shelve_store import ShelveJobStore

	sched = Scheduler()
	sched.add_jobstore(ShelveJobStore('/tmp/dbfile'), 'file')

The example configuration above results in the scheduler having two
job stores -- one
(:class:`~apscheduler.jobstores.ram_store.RAMJobStore`) and one
(:class:`~apscheduler.jobstores.shelve_store.ShelveJobStore`).

In addition to the built-in job stores, it is possible to extend APScheduler to
support other persistence mechanisms as well. See the
:doc:`Extending APScheduler <extending>` section for details.


Job persistency
---------------

The built-in job stores (save the
:class:`~apscheduler.jobstores.ram_store.RAMJobStore`) store jobs in a durable
manner. This means that when you schedule jobs in them, shut down the scheduler,
restart it and readd the job store in question, it will load the previously
scheduled jobs automatically. It can automatically find the callback function
using a textual reference saved when the job was added. Unfortunately this
means that **you can only schedule top level functions with persistent job
stores**. The job store will raise an exception if you attempt to schedule a
noncompliant callable.


Triggers
--------

Triggers determine the times when the jobs should be run.
APScheduler comes with three built-in triggers --
:class:`~apscheduler.triggers.simple.SimpleTrigger`,
:class:`~apscheduler.triggers.interval.IntervalTrigger` and
:class:`~apscheduler.triggers.cron.CronTrigger`. You don't normally use these
directly, since the scheduler has shortcut methods for these built-in
triggers, as discussed in the next section.


Limiting the concurrently executing instances of a job
------------------------------------------------------

By default, no two instances of the same job will be run concurrently. This
means that if the job is about to be run but the previous run hasn't finished
yet, then the latest run is considered a misfire. It is possible to set the
maximum number of instances for a particular job that the scheduler will let
run concurrently, by using the ``max_concurrency`` keyword argument when adding
the job.


Coalescing job executions
-------------------------

Sometimes the scheduler may be unable to execute a scheduled job at the time
it was scheduled to run. The most common case is when a job is scheduled in a
persistent job store and the scheduler is shut down and restarted after the job
was supposed to execute. Normally the scheduler would execute the job as many
times as its misfire_grace_time option permits. This can be undesireable in
many cases, such as backing up data or sending notifications. By setting the
``coalesce`` option to ``True`` when adding the job (or globally on the
scheduler) you can avoid unintended successive executions of the job. The
bypassed runs of the job are not considered misfires nor do they count towards
any maximum run count of the job.


Scheduler events
----------------

It is possible to attach event listeners to the scheduler. Scheduler events are
fired on certain occasions, and may carry additional information in them
concerning the details of that particular event. It is possible to listen to
only particular types of events by giving the appropriate ``mask`` argument to
:meth:`~apscheduler.scheduler.Scheduler.add_listener`, OR'ing
the different constants together. The listener callable is called with one
argument, the event object. The type of the event object is tied to the event
code as shown below:

========================== ============== ==========================================
Constant                   Event class    Triggered when...
========================== ============== ==========================================
EVENT_SCHEDULER_START      SchedulerEvent The scheduler is started
EVENT_SCHEDULER_SHUTDOWN   SchedulerEvent The scheduler is shut down
EVENT_JOBSTORE_ADDED       JobStoreEvent  A job store is added to the scheduler
EVENT_JOBSTORE_REMOVED     JobStoreEvent  A job store is removed from the scheduler
EVENT_JOBSTORE_JOB_ADDED   JobStoreEvent  A job is added to a job store
EVENT_JOBSTORE_JOB_REMOVED JobStoreEvent  A job is removed from a job store
EVENT_JOB_EXECUTED         JobEvent       A job is executed successfully
EVENT_JOB_ERROR            JobEvent       A job raised an exception during execution
EVENT_JOB_MISSED           JobEvent       A job's execution time is missed
========================== ============== ==========================================

See the documentation for the :mod:`~apscheduler.events` module for specifics
on the available event attributes.

Example::

    def my_listener(event):
        if event.exception:
            print 'The job crashed :('
        else:
            print 'The job worked :)'

    scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)


Getting a list of scheduled jobs
--------------------------------

If you want to see which jobs are currently added in the scheduler, you can
simply do::

	sched.print_jobs()

This will print a human-readable listing of scheduled jobs, their triggering
mechanisms and the next time they will fire. If you supply a file-like object
as an argument to this method, it will output the results in that file.

To get a machine processable list of the scheduled jobs, you can use the
:meth:`~apscheduler.scheduler.Scheduler.get_jobs` scheduler method. It will
return a list of :class:`~apscheduler.job.Job` instances.


FAQ
===

Q: Why do my processes hang instead of exiting when they are finished?

A: A scheduled job may still be executing. APScheduler's thread pool is wired
to wait for the job threads to exit before allowing the interpreter to exit to
avoid unpredictable behavior caused by the shutdown procedures of the Python
interpreter. A more thorough explanation
`can be found here <http://joeshaw.org/2009/02/24/605>`_.


Getting help
============

If you have problems or other questions, you can either:

* Join the ``#apscheduler`` channel on
  `Freenode IRC <http://freenode.net/irc_servers.shtml>`_, or
* Send email to <apscheduler at nextday dot fi>


Reporting bugs
==============

A `bug tracker <http://bitbucket.org/agronholm/apscheduler/issues/>`_
is provided by bitbucket.org.


.. include:: ../CHANGES.rst


Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`