Commit b6e2ffce authored by SVN-Git Migration's avatar SVN-Git Migration

Imported Upstream version 2.4.5

parents
=========
AUTHORS
=========
:order: sorted
Aaron Ross <aaron@wawd.com>
Adam Endicott
Adriano Petrich <petrich@gmail.com>
Ales Zoulek <ales.zoulek@gmail.com>
Allan Caffee <allan.caffee@gmail.com>
Andrew Watts <andrewwatts@gmail.com>
Armin Ronacher <armin.ronacher@active-4.com>
Ask Solem <ask@celeryproject.org>
Augusto Becciu <augusto@becciu.org>
Balachandran C <balachandran.c@gramvaani.org>
Bartosz Ptaszynski
Ben Firshman <ben@firshman.co.uk>
Brad Jasper <bjasper@gmail.com>
Branko Čibej <brane@apache.org>
Brian Rosner <brosner@gmail.com>
Bryan Berg <bryan@mixedmedialabs.com>
Chase Seibert <chase.seibert+github@gmail.com>
Chris Adams <chris@improbable.org>
Chris Rose <offby1@offby1.net>
Chris Streeter <chris@chrisstreeter.com>
Christoph Burgmer <christoph@nwebs.de>
Christopher Peplin <peplin@bueda.com>
Clay Gerrard
Dan McGee <dan@archlinux.org>
Daniel Watkins <daniel@daniel-watkins.co.uk>
David Arthur <mumrah@gmail.com>
David Cramer <dcramer@gmail.com>
David Miller <il.livid.dream@gmail.com>
David Strauss <david@davidstrauss.net>
David White <dpwhite2@ncsu.edu>
Felix Berger <bflat1@gmx.net
Frédéric Junod <frederic.junod@camptocamp.com>
Gert Van Gool <gertvangool@gmail.com>
Greg Haskins <greg@greghaskins.com>
Grégoire Cachet <gregoire@audacy.fr>
Gunnlaugur Thor Briem <gunnlaugur@gmail.com>
Hari <haridara@gmail.com>
Harm Verhagen <harm.verhagen@gmail.com>
Honza Kral <honza.kral@gmail.com>
Ionel Maries Cristian <contact@ionelmc.ro>
Jannis Leidel <jannis@leidel.info>
Jason Baker <amnorvend@gmail.com>
Jeff Balogh <me@jeffbalogh.org>
Jeff Terrace <jterrace@gmail.com>
Jerzy Kozera <jerzy.kozera@gmail.com>
Jesper Noehr <jesper@noehr.org>
John Watson <johnw@mahalo.com>
Jonas Haag <jonas@lophus.org>
Jonatan Heyman <jonatan@heyman.info>
Joshua Ginsberg <jag@flowtheory.net>
Juan Ignacio Catalano <catalanojuan@gmail.com>
Juarez Bochi <jbochi@gmail.com>
Jude Nagurney <jude@pwan.org>
Julien Poissonnier <julien@caffeine.lu>
Kevin Tran <hekevintran@gmail.com>
Kornelijus Survila <kornholijo@gmail.com>
Leo Dirac <leo@banyanbranch.com>
Lukas Linhart <lukas.linhart@centrumholdings.com>
Marcin Kuźmiński <marcin@python-works.com>
Marcin Lulek <info@webreactor.eu>
Mark Hellewell <mark.hellewell@gmail.com>
Mark Stover <stovenator@gmail.com>
Martin Galpin <m@66laps.com>
Matthew J Morrison <mattj.morrison@gmail.com>
Mauro Rocco <fireantology@gmail.com>
Maxim Bodyansky <bodyansky@gmail.com>
Michael Elsdoerfer <michael@elsdoerfer.com>
Miguel Hernandez Martos <enlavin@gmail.com>
Mikhail Gusarov <dottedmag@dottedmag.net>
Mikhail Korobov <kmike84@gmail.com>
Mitar <mitar@tnode.com>
Neil Chintomby <neil@mochimedia.com>
Noah Kantrowitz <noah@coderanger.net>
Norman Richards <orb@nostacktrace.com>
Patrick Altman <paltman@gmail.com>
Piotr Sikora <piotr.sikora@frickle.com>
Remy Noel <mocramis@gmail.com>
Reza Lotun <rlotun@gmail.com>
Roberto Gaiser <gaiser@geekbunker.org>
Rune Halvorsen <runefh@gmail.com>
Ryan Petrello <lists@ryanpetrello.com>
Sam Cooke <sam@mixcloud.com>
Sean Creeley <sean.creeley@gmail.com>
Simon Josi <simon.josi@atizo.com>
Steeve Morin <steeve.morin@gmail.com>
Stefan Kjartansson <esteban.supreme@gmail.com>
Timo Sugliani
Vincent Driessen <vincent@datafox.nl>
Vitaly Babiy <vbabiy86@gmail.com>
Vladimir Kryachko <vladimir.kryachko@etvnet.com>
Wes Turner <wes.turner@gmail.com>
Wes Winham <winhamwr@gmail.com>
jpellerin
kuno <neokuno@gmail.com>
lookfwd <lookfwd@gmail.com>
sdcooke
This diff is collapsed.
This diff is collapsed.
Installing Celery
=================
You can install Celery either via the Python Package Index (PyPI)
or from source.
To install using `pip`::
$ pip install Celery
To install using `easy_install`::
$ easy_install Celery
If you have downloaded a source tarball you can install it
by doing the following::
$ python setup.py build
# python setup.py install # as root
Copyright (c) 2009-2011, Ask Solem & contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Ask Solem nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Ask Solem OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
include AUTHORS
include Changelog
include FAQ
include INSTALL
include README
include README.rst
include MANIFEST.in
include LICENSE
include TODO
include THANKS
include setup.cfg
recursive-include celery *.py
recursive-include funtests *.py
recursive-include docs *
recursive-include contrib *
recursive-include examples *
recursive-include requirements *.txt
prune tests/*.pyc
prune docs/*.pyc
prune contrib/*.pyc
prune celery/*.pyc
prune examples/*.pyc
prune bin/*.pyc
prune docs/.build
prune docs/graffles
prune .tox/*
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Thanks to Rune Halvorsen <runeh@opera.com> for the name.
Thanks to Anton Tsigularov <antont@opera.com> for the previous name (crunchy)
which we had to abandon because of an existing project with that name.
Thanks to Martin Mahner for the Sphinx theme.
Thanks to Brian K. Jones for bunny.py (http://github.com/bkjones/bunny), the
tool that inspired camqadm.
Please see our Issue Tracker at GitHub:
http://github.com/ask/celery/issues
This diff is collapsed.
This diff is collapsed.
[console_scripts]
celeryctl = celery.bin.celeryctl:main
celeryd = celery.bin.celeryd:main
camqadm = celery.bin.camqadm:main
celeryev = celery.bin.celeryev:main
celeryd-multi = celery.bin.celeryd_multi:main
celerybeat = celery.bin.celerybeat:main
[bundle.bundles]
celery = celery.contrib.bundles:bundles
anyjson>=0.3.1
kombu>=1.4.3,<3.0.0
python-dateutil>=1.5.0,<2.0.0
\ No newline at end of file
# -*- coding: utf-8 -*-
"""Distributed Task Queue"""
# :copyright: (c) 2009 - 2011 by Ask Solem.
# :license: BSD, see LICENSE for more details.
from __future__ import absolute_import
import os
import sys
VERSION = (2, 4, 5)
__version__ = ".".join(map(str, VERSION[0:3])) + "".join(VERSION[3:])
__author__ = "Ask Solem"
__contact__ = "ask@celeryproject.org"
__homepage__ = "http://celeryproject.org"
__docformat__ = "restructuredtext"
if sys.version_info < (2, 5):
raise Exception(
"Python 2.4 is not supported by this version. "
"Please use Celery versions 2.1.x or earlier.")
def Celery(*args, **kwargs):
from .app import App
return App(*args, **kwargs)
if not os.environ.get("CELERY_NO_EVAL", False):
from .local import Proxy
def _get_current_app():
from .app import current_app
return current_app()
current_app = Proxy(_get_current_app)
# -*- coding: utf-8 -*-
"""
celery.app
~~~~~~~~~~
Celery Application.
:copyright: (c) 2009 - 2011 by Ask Solem.
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import
import os
import threading
from functools import wraps
from inspect import getargspec
from .. import registry
from ..utils import cached_property, instantiate
from . import base
# Apps with the :attr:`~celery.app.base.BaseApp.set_as_current` attribute
# sets this, so it will always contain the last instantiated app,
# and is the default app returned by :func:`app_or_default`.
_tls = threading.local()
_tls.current_app = None
class AppPickler(object):
def __call__(self, cls, *args):
kwargs = self.build_kwargs(*args)
app = self.construct(cls, **kwargs)
self.prepare(app, **kwargs)
return app
def prepare(self, app, **kwargs):
app.conf.update(kwargs["changes"])
def build_kwargs(self, *args):
return self.build_standard_kwargs(*args)
def build_standard_kwargs(self, main, changes, loader, backend, amqp,
events, log, control, accept_magic_kwargs):
return dict(main=main, loader=loader, backend=backend, amqp=amqp,
changes=changes, events=events, log=log, control=control,
set_as_current=False,
accept_magic_kwargs=accept_magic_kwargs)
def construct(self, cls, **kwargs):
return cls(**kwargs)
def _unpickle_app(cls, pickler, *args):
return pickler()(cls, *args)
class App(base.BaseApp):
"""Celery Application.
:param main: Name of the main module if running as `__main__`.
:keyword loader: The loader class, or the name of the loader class to use.
Default is :class:`celery.loaders.app.AppLoader`.
:keyword backend: The result store backend class, or the name of the
backend class to use. Default is the value of the
:setting:`CELERY_RESULT_BACKEND` setting.
:keyword amqp: AMQP object or class name.
:keyword events: Events object or class name.
:keyword log: Log object or class name.
:keyword control: Control object or class name.
:keyword set_as_current: Make this the global current app.
"""
Pickler = AppPickler
def set_current(self):
"""Make this the current app for this thread."""
_tls.current_app = self
def on_init(self):
if self.set_as_current:
self.set_current()
def create_task_cls(self):
"""Creates a base task class using default configuration
taken from this app."""
conf = self.conf
from .task import BaseTask
class Task(BaseTask):
abstract = True
app = self
backend = self.backend
exchange_type = conf.CELERY_DEFAULT_EXCHANGE_TYPE
delivery_mode = conf.CELERY_DEFAULT_DELIVERY_MODE
send_error_emails = conf.CELERY_SEND_TASK_ERROR_EMAILS
error_whitelist = conf.CELERY_TASK_ERROR_WHITELIST
serializer = conf.CELERY_TASK_SERIALIZER
rate_limit = conf.CELERY_DEFAULT_RATE_LIMIT
track_started = conf.CELERY_TRACK_STARTED
acks_late = conf.CELERY_ACKS_LATE
ignore_result = conf.CELERY_IGNORE_RESULT
store_errors_even_if_ignored = \
conf.CELERY_STORE_ERRORS_EVEN_IF_IGNORED
accept_magic_kwargs = self.accept_magic_kwargs
Task.__doc__ = BaseTask.__doc__
return Task
def Worker(self, **kwargs):
"""Create new :class:`~celery.apps.worker.Worker` instance."""
return instantiate("celery.apps.worker.Worker", app=self, **kwargs)
def Beat(self, **kwargs):
"""Create new :class:`~celery.apps.beat.Beat` instance."""
return instantiate("celery.apps.beat.Beat", app=self, **kwargs)
def TaskSet(self, *args, **kwargs):
"""Create new :class:`~celery.task.sets.TaskSet`."""
from ..task.sets import TaskSet
kwargs["app"] = self
return TaskSet(*args, **kwargs)
def worker_main(self, argv=None):
"""Run :program:`celeryd` using `argv`. Uses :data:`sys.argv`
if `argv` is not specified."""
from ..bin.celeryd import WorkerCommand
return WorkerCommand(app=self).execute_from_commandline(argv)
def task(self, *args, **options):
"""Decorator to create a task class out of any callable.
.. admonition:: Examples
.. code-block:: python
@task()
def refresh_feed(url):
return Feed.objects.get(url=url).refresh()
With setting extra options and using retry.
.. code-block:: python
@task(exchange="feeds")
def refresh_feed(url, **kwargs):
try:
return Feed.objects.get(url=url).refresh()
except socket.error, exc:
refresh_feed.retry(args=[url], kwargs=kwargs, exc=exc)
Calling the resulting task:
>>> refresh_feed("http://example.com/rss") # Regular
<Feed: http://example.com/rss>
>>> refresh_feed.delay("http://example.com/rss") # Async
<AsyncResult: 8998d0f4-da0b-4669-ba03-d5ab5ac6ad5d>
"""
def inner_create_task_cls(**options):
def _create_task_cls(fun):
options["app"] = self
options.setdefault("accept_magic_kwargs", False)
base = options.pop("base", None) or self.Task
@wraps(fun, assigned=("__module__", "__name__"))
def run(self, *args, **kwargs):
return fun(*args, **kwargs)
# Save the argspec for this task so we can recognize
# which default task kwargs we're going to pass to it later.
# (this happens in celery.utils.fun_takes_kwargs)
run.argspec = getargspec(fun)
cls_dict = dict(options, run=run,
__module__=fun.__module__,
__doc__=fun.__doc__)
T = type(fun.__name__, (base, ), cls_dict)()
return registry.tasks[T.name] # global instance.
return _create_task_cls
if len(args) == 1 and callable(args[0]):
return inner_create_task_cls(**options)(*args)
return inner_create_task_cls(**options)
@cached_property
def Task(self):
"""Default Task base class for this application."""
return self.create_task_cls()
def __repr__(self):
return "<Celery: %s:0x%x>" % (self.main or "__main__", id(self), )
def __reduce__(self):
# Reduce only pickles the configuration changes,
# so the default configuration doesn't have to be passed
# between processes.
return (_unpickle_app, (self.__class__, self.Pickler)
+ self.__reduce_args__())
def __reduce_args__(self):
return (self.main,
self.conf.changes,
self.loader_cls,
self.backend_cls,
self.amqp_cls,
self.events_cls,
self.log_cls,
self.control_cls,
self.accept_magic_kwargs)
#: The "default" loader is the default loader used by old applications.
default_loader = os.environ.get("CELERY_LOADER") or "default"
#: Global fallback app instance.
default_app = App("default", loader=default_loader,
set_as_current=False, accept_magic_kwargs=True)
def current_app():
return getattr(_tls, "current_app", None) or default_app
def _app_or_default(app=None):
"""Returns the app provided or the default app if none.
The environment variable :envvar:`CELERY_TRACE_APP` is used to
trace app leaks. When enabled an exception is raised if there
is no active app.
"""
if app is None:
return getattr(_tls, "current_app", None) or default_app
return app
def _app_or_default_trace(app=None): # pragma: no cover
from traceback import print_stack
from multiprocessing import current_process
if app is None:
if getattr(_tls, "current_app", None):
print("-- RETURNING TO CURRENT APP --") # noqa+
print_stack()
return _tls.current_app
if current_process()._name == "MainProcess":
raise Exception("DEFAULT APP")
print("-- RETURNING TO DEFAULT APP --") # noqa+
print_stack()
return default_app
return app
def enable_trace():
global app_or_default
app_or_default = _app_or_default_trace
def disable_trace():
global app_or_default
app_or_default = _app_or_default
app_or_default = _app_or_default
if os.environ.get("CELERY_TRACE_APP"): # pragma: no cover
enable_trace()
This diff is collapsed.
This diff is collapsed.
# -*- coding: utf-8 -*-
"""
celery.app.defaults
~~~~~~~~~~~~~~~~~~~
Configuration introspection and defaults.
:copyright: (c) 2009 - 2011 by Ask Solem.
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import
import sys
from collections import deque
from datetime import timedelta
is_jython = sys.platform.startswith("java")
is_pypy = hasattr(sys, "pypy_version_info")