Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

base.py 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.task.base
  4. ~~~~~~~~~~~~~~~~
  5. The task implementation has been moved to :mod:`celery.app.task`.
  6. This contains the backward compatible Task class used in the old API,
  7. and shouldn't be used in new applications.
  8. """
  9. from __future__ import absolute_import
  10. from kombu import Exchange
  11. from celery import current_app
  12. from celery.app.task import Context, TaskType, Task as BaseTask # noqa
  13. from celery.five import class_property, reclassmethod
  14. from celery.schedules import maybe_schedule
  15. from celery.utils.log import get_task_logger
  16. __all__ = ['Task', 'PeriodicTask', 'task']
  17. #: list of methods that must be classmethods in the old API.
  18. _COMPAT_CLASSMETHODS = (
  19. 'delay', 'apply_async', 'retry', 'apply', 'subtask_from_request',
  20. 'AsyncResult', 'subtask', '_get_request', '_get_exec_options',
  21. )
  22. class Task(BaseTask):
  23. """Deprecated Task base class.
  24. Modern applications should use :class:`celery.Task` instead.
  25. """
  26. abstract = True
  27. __bound__ = False
  28. __v2_compat__ = True
  29. # - Deprecated compat. attributes -:
  30. queue = None
  31. routing_key = None
  32. exchange = None
  33. exchange_type = None
  34. delivery_mode = None
  35. mandatory = False # XXX deprecated
  36. immediate = False # XXX deprecated
  37. priority = None
  38. type = 'regular'
  39. disable_error_emails = False
  40. accept_magic_kwargs = False
  41. from_config = BaseTask.from_config + (
  42. ('exchange_type', 'CELERY_DEFAULT_EXCHANGE_TYPE'),
  43. ('delivery_mode', 'CELERY_DEFAULT_DELIVERY_MODE'),
  44. )
  45. # In old Celery the @task decorator didn't exist, so one would create
  46. # classes instead and use them directly (e.g. MyTask.apply_async()).
  47. # the use of classmethods was a hack so that it was not necessary
  48. # to instantiate the class before using it, but it has only
  49. # given us pain (like all magic).
  50. for name in _COMPAT_CLASSMETHODS:
  51. locals()[name] = reclassmethod(getattr(BaseTask, name))
  52. @class_property
  53. def request(cls):
  54. return cls._get_request()
  55. @class_property
  56. def backend(cls):
  57. if cls._backend is None:
  58. return cls.app.backend
  59. return cls._backend
  60. @backend.setter
  61. def backend(cls, value): # noqa
  62. cls._backend = value
  63. @classmethod
  64. def get_logger(self, **kwargs):
  65. return get_task_logger(self.name)
  66. @classmethod
  67. def establish_connection(self):
  68. """Deprecated method used to get a broker connection.
  69. Should be replaced with :meth:`@Celery.connection`
  70. instead, or by acquiring connections from the connection pool:
  71. .. code-block:: python
  72. # using the connection pool
  73. with celery.pool.acquire(block=True) as conn:
  74. ...
  75. # establish fresh connection
  76. with celery.connection() as conn:
  77. ...
  78. """
  79. return self._get_app().connection()
  80. def get_publisher(self, connection=None, exchange=None,
  81. exchange_type=None, **options):
  82. """Deprecated method to get the task publisher (now called producer).
  83. Should be replaced with :class:`@amqp.TaskProducer`:
  84. .. code-block:: python
  85. with celery.connection() as conn:
  86. with celery.amqp.TaskProducer(conn) as prod:
  87. my_task.apply_async(producer=prod)
  88. """
  89. exchange = self.exchange if exchange is None else exchange
  90. if exchange_type is None:
  91. exchange_type = self.exchange_type
  92. connection = connection or self.establish_connection()
  93. return self._get_app().amqp.TaskProducer(
  94. connection,
  95. exchange=exchange and Exchange(exchange, exchange_type),
  96. routing_key=self.routing_key, **options
  97. )
  98. @classmethod
  99. def get_consumer(self, connection=None, queues=None, **kwargs):
  100. """Deprecated method used to get consumer for the queue
  101. this task is sent to.
  102. Should be replaced with :class:`@amqp.TaskConsumer` instead:
  103. """
  104. Q = self._get_app().amqp
  105. connection = connection or self.establish_connection()
  106. if queues is None:
  107. queues = Q.queues[self.queue] if self.queue else Q.default_queue
  108. return Q.TaskConsumer(connection, queues, **kwargs)
  109. class PeriodicTask(Task):
  110. """A periodic task is a task that adds itself to the
  111. :setting:`CELERYBEAT_SCHEDULE` setting."""
  112. abstract = True
  113. ignore_result = True
  114. relative = False
  115. options = None
  116. compat = True
  117. def __init__(self):
  118. if not hasattr(self, 'run_every'):
  119. raise NotImplementedError(
  120. 'Periodic tasks must have a run_every attribute')
  121. self.run_every = maybe_schedule(self.run_every, self.relative)
  122. super(PeriodicTask, self).__init__()
  123. @classmethod
  124. def on_bound(cls, app):
  125. app.conf.CELERYBEAT_SCHEDULE[cls.name] = {
  126. 'task': cls.name,
  127. 'schedule': cls.run_every,
  128. 'args': (),
  129. 'kwargs': {},
  130. 'options': cls.options or {},
  131. 'relative': cls.relative,
  132. }
  133. def task(*args, **kwargs):
  134. """Deprecated decorator, please use :func:`celery.task`."""
  135. return current_app.task(*args, **dict({'accept_magic_kwargs': False,
  136. 'base': Task}, **kwargs))
  137. def periodic_task(*args, **options):
  138. """Deprecated decorator, please use :setting:`CELERYBEAT_SCHEDULE`."""
  139. return task(**dict({'base': PeriodicTask}, **options))