methods.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.contrib.methods
  4. ======================
  5. Task decorator that supports creating tasks out of methods.
  6. Examples
  7. --------
  8. .. code-block:: python
  9. from celery.contrib.methods import task
  10. class X(object):
  11. @task()
  12. def add(self, x, y):
  13. return x + y
  14. or with any task decorator:
  15. .. code-block:: python
  16. from celery.contrib.methods import task_method
  17. class X(object):
  18. @celery.task(filter=task_method)
  19. def add(self, x, y):
  20. return x + y
  21. .. note::
  22. The task must use the new Task base class (:class:`celery.Task`),
  23. and the old base class using classmethods (``celery.task.Task``,
  24. ``celery.task.base.Task``).
  25. This means that you have to use the task decorator from a Celery app
  26. instance, and not the old-API:
  27. .. code-block:: python
  28. from celery import task # BAD
  29. from celery.task import task # ALSO BAD
  30. # GOOD:
  31. celery = Celery(...)
  32. @celery.task(filter=task_method)
  33. def foo(self): pass
  34. # ALSO GOOD:
  35. from celery import current_app
  36. @current_app.task(filter=task_method)
  37. def foo(self): pass
  38. Caveats
  39. -------
  40. - Automatic naming won't be able to know what the class name is.
  41. The name will still be module_name + task_name,
  42. so two methods with the same name in the same module will collide
  43. so that only one task can run:
  44. .. code-block:: python
  45. class A(object):
  46. @task()
  47. def add(self, x, y):
  48. return x + y
  49. class B(object):
  50. @task()
  51. def add(self, x, y):
  52. return x + y
  53. would have to be written as:
  54. .. code-block:: python
  55. class A(object):
  56. @task(name='A.add')
  57. def add(self, x, y):
  58. return x + y
  59. class B(object):
  60. @task(name='B.add')
  61. def add(self, x, y):
  62. return x + y
  63. """
  64. from __future__ import absolute_import
  65. from celery import current_app
  66. __all__ = ['task_method', 'task']
  67. class task_method(object):
  68. def __init__(self, task, *args, **kwargs):
  69. self.task = task
  70. def __get__(self, obj, type=None):
  71. if obj is None:
  72. return self.task
  73. task = self.task.__class__()
  74. task.__self__ = obj
  75. return task
  76. def task(*args, **kwargs):
  77. return current_app.task(*args, **dict(kwargs, filter=task_method))