class Command(BaseCommand): help = "" args = "" version = __version__ prog_name = "celery" show_body = True option_list = ( Option("--quiet", "-q", action="store_true"), Option("--no-color", "-C", action="store_true"), ) def __init__(self, app=None, no_color=False, stdout=sys.stdout, stderr=sys.stderr): super(Command, self).__init__(app=app) self.colored = term.colored(enabled=not no_color) self.stdout = stdout self.stderr = stderr self.quiet = False def __call__(self, *args, **kwargs): try: ret = self.run(*args, **kwargs) except Error, exc: self.error(self.colored.red("Error: %s" % exc)) return exc.status return ret if ret is not None else EX_OK
def get_options(self): return ( Option('-Q', '--queue'), Option('-S', '--strategy', default='simple'), Option('-l', '--loglevel'), Option('--labels', default=''), )
def get_options(self): conf = self.app.conf return ( Option('--detach', default=False, action="store_true", dest="detach", help="Detach and run in the background."), Option('-s', '--schedule', default=conf.CELERYBEAT_SCHEDULE_FILENAME, action="store", dest="schedule", help="Path to the schedule database. The extension " "'.db' will be appended to the filename. Default: %s" % (conf.CELERYBEAT_SCHEDULE_FILENAME, )), Option('--max-interval', default=None, type="float", dest="max_interval", help="Max. seconds to sleep between schedule iterations."), Option('-S', '--scheduler', default=None, action="store", dest="scheduler_cls", help="Scheduler class. Default is " "celery.beat:PersistentScheduler"), Option('-l', '--loglevel', default=conf.CELERYBEAT_LOG_LEVEL, action="store", dest="loglevel", help="Loglevel. One of DEBUG/INFO/WARNING/ERROR/CRITICAL."))
class result(Command): """Gives the return value for a given task id. Examples:: celery result 8f511516-e2f5-4da4-9d2f-0fb83a86e500 celery result 8f511516-e2f5-4da4-9d2f-0fb83a86e500 -t tasks.add celery result 8f511516-e2f5-4da4-9d2f-0fb83a86e500 --traceback """ args = '<task_id>' option_list = Command.option_list + ( Option('--task', '-t', help='name of task (if custom backend)'), Option( '--traceback', action='store_true', help='show traceback instead'), ) def run(self, task_id, *args, **kwargs): result_cls = self.app.AsyncResult task = kwargs.get('task') traceback = kwargs.get('traceback', False) if task: result_cls = self.app.tasks[task].AsyncResult result = result_cls(task_id) if traceback: value = result.traceback else: value = result.get() self.out(self.pretty(value)[1])
class Command(BaseCommand): help = '' args = '' prog_name = 'celery' show_body = True show_reply = True option_list = ( Option('--quiet', '-q', action='store_true'), Option('--no-color', '-C', action='store_true', default=None), ) def __init__(self, app=None, no_color=False, stdout=sys.stdout, stderr=sys.stderr, show_reply=True): super(Command, self).__init__(app=app) self.colored = term.colored(enabled=not no_color) self.stdout = stdout self.stderr = stderr self.quiet = False if show_reply is not None: self.show_reply = show_reply def __call__(self, *args, **kwargs): try: ret = self.run(*args, **kwargs) except Error, exc: self.error(self.colored.red('Error: %s' % exc)) return exc.status return ret if ret is not None else EX_OK
class purge(Command): """Erase all messages from all known task queues. WARNING: There is no undo operation for this command. """ warn_prelude = ( '{warning}: This will remove all tasks from {queues}: {names}.\n' ' There is no undo for this operation!\n\n' '(to skip this prompt use the -f option)\n') warn_prompt = 'Are you sure you want to delete all tasks' fmt_purged = 'Purged {mnum} {messages} from {qnum} known task {queues}.' fmt_empty = 'No messages purged from {qnum} {queues}' option_list = Command.option_list + ( Option('--force', '-f', action='store_true', help='Do not prompt for verification'), Option('--queues', '-Q', default=[], help='Comma separated list of queue names to purge.'), Option('--exclude-queues', '-X', default=[], help='Comma separated list of queues names not to purge.')) def run(self, force=False, queues=None, exclude_queues=None, **kwargs): queues = set(str_to_list(queues or [])) exclude = set(str_to_list(exclude_queues or [])) names = (queues or set(keys(self.app.amqp.queues))) - exclude qnum = len(names) messages = None if names: if not force: self.out( self.warn_prelude.format( warning=self.colored.red('WARNING'), queues=text.pluralize(qnum, 'queue'), names=', '.join(sorted(names)), )) if self.ask(self.warn_prompt, ('yes', 'no'), 'no') != 'yes': return with self.app.connection_for_write() as conn: messages = sum(self._purge(conn, queue) for queue in names) fmt = self.fmt_purged if messages else self.fmt_empty self.out( fmt.format(mnum=messages, qnum=qnum, messages=text.pluralize(messages, 'message'), queues=text.pluralize(qnum, 'queue'))) def _purge(self, conn, queue): try: return conn.default_channel.queue_purge(queue) or 0 except conn.channel_errors: return 0
def get_options(self): c = self.app.conf return ( Option('--detach', action='store_true'), Option('-s', '--schedule', default=c.CELERYBEAT_SCHEDULE_FILENAME), Option('--max-interval', type='float'), Option('-S', '--scheduler', dest='scheduler_cls'), Option('-l', '--loglevel', default=c.CELERYBEAT_LOG_LEVEL), ) + daemon_options(default_pidfile='celerybeat.pid')
def get_options(self): c = self.app.conf return ((Option('--detach', action='store_true'), Option('-s', '--schedule', default=c.beat_schedule_filename), Option('--max-interval', type='float'), Option('-S', '--scheduler', dest='scheduler_cls'), Option('-l', '--loglevel', default='WARN')) + daemon_options(default_pidfile='celerybeat.pid') + tuple(self.app.user_options['beat']))
def get_options(self): c = self.app.conf return ( Option('--detach', action="store_true"), Option('-s', '--schedule', default=c.CELERYBEAT_SCHEDULE_FILENAME), Option('--max-interval', type="float"), Option('-S', '--scheduler', dest="scheduler_cls"), Option('-l', '--loglevel', default=c.CELERYBEAT_LOG_LEVEL), )
class call(Command): """Call a task by name. Examples:: celery call tasks.add --args='[2, 2]' celery call tasks.add --args='[2, 2]' --countdown=10 """ args = '<task_name>' option_list = Command.option_list + ( Option('--args', '-a', help='positional arguments (json).'), Option('--kwargs', '-k', help='keyword arguments (json).'), Option('--eta', help='scheduled time (ISO-8601).'), Option('--countdown', type='float', help='eta in seconds from now (float/int).'), Option('--expires', help='expiry time (ISO-8601/float/int).'), Option('--serializer', default='json', help='defaults to json.'), Option('--queue', help='custom queue name.'), Option('--exchange', help='custom exchange name.'), Option('--routing-key', help='custom routing key.'), ) def run(self, name, *_, **kw): # Positional args. args = kw.get('args') or () if isinstance(args, string_t): args = anyjson.loads(args) # Keyword args. kwargs = kw.get('kwargs') or {} if isinstance(kwargs, string_t): kwargs = anyjson.loads(kwargs) # Expires can be int/float. expires = kw.get('expires') or None try: expires = float(expires) except (TypeError, ValueError): # or a string describing an ISO 8601 datetime. try: expires = maybe_iso8601(expires) except (TypeError, ValueError): raise res = self.app.send_task(name, args=args, kwargs=kwargs, countdown=kw.get('countdown'), serializer=kw.get('serializer'), queue=kw.get('queue'), exchange=kw.get('exchange'), routing_key=kw.get('routing_key'), eta=maybe_iso8601(kw.get('eta')), expires=expires) self.out(res.id)
class purge(Command): """Erase all messages from all known task queues. WARNING: There is no undo operation for this command. """ warn_prelude = ( '{warning}: This will remove all tasks from {queues}: {names}.\n' ' There is no undo for this operation!\n\n' '(to skip this prompt use the -f option)\n' ) warn_prompt = 'Are you sure you want to delete all tasks' fmt_purged = 'Purged {mnum} {messages} from {qnum} known task {queues}.' fmt_empty = 'No messages purged from {qnum} {queues}' option_list = Command.option_list + ( Option('--force', '-f', action='store_true', help='Do not prompt for verification'), ) def run(self, force=False, **kwargs): names = list(sorted(self.app.amqp.queues.keys())) qnum = len(names) if not force: self.out(self.warn_prelude.format( warning=self.colored.red('WARNING'), queues=text.pluralize(qnum, 'queue'), names=', '.join(names), )) if self.ask(self.warn_prompt, ('yes', 'no'), 'no') != 'yes': return messages = self.app.control.purge() fmt = self.fmt_purged if messages else self.fmt_empty self.out(fmt.format( mnum=messages, qnum=qnum, messages=text.pluralize(messages, 'message'), queues=text.pluralize(qnum, 'queue')))
def test_parse_preload_options_without_equals_and_append(self): cmd = Command() opt = Option('--zoom', action='append', default=[]) cmd.preload_options = (opt, ) acc = cmd.parse_preload_options(['--zoom', '1', '--zoom', '2']) self.assertEqual(acc, {'zoom': ['1', '2']})
def test_with_cmdline_config(self, app): cmd = MockCommand(app=app) cmd.enable_config_from_cmdline = True cmd.namespace = 'worker' rest = cmd.setup_app_from_commandline(argv=[ '--loglevel=INFO', '--', 'result.backend=redis://backend.example.com', 'broker.url=amqp://broker.example.com', '.prefetch_multiplier=100']) assert cmd.app.conf.result_backend == 'redis://backend.example.com' assert cmd.app.conf.broker_url == 'amqp://broker.example.com' assert cmd.app.conf.worker_prefetch_multiplier == 100 assert rest == ['--loglevel=INFO'] cmd.app = None cmd.get_app = Mock(name='get_app') cmd.get_app.return_value = app app.user_options['preload'] = [ Option('--foo', action='store_true'), ] cmd.setup_app_from_commandline(argv=[ '--foo', '--loglevel=INFO', '--', 'broker.url=amqp://broker.example.com', '.prefetch_multiplier=100']) assert cmd.app is cmd.get_app()
def get_options(self): return ( Option('-i', '--iterations', type='int', default=50, help='Number of iterations for each test'), Option('-n', '--numtests', type='int', default=None, help='Number of tests to execute'), Option('-o', '--offset', type='int', default=0, help='Start at custom offset'), Option('--block-timeout', type='int', default=30 * 60), Option('-l', '--list', action='store_true', dest='list_all', default=False, help='List all tests'), Option('-r', '--repeat', type='float', default=0, help='Number of times to repeat the test suite'), Option('-g', '--group', default='all', help='Specify test group (all|green|redis)'), Option('--diag', default=False, action='store_true', help='Enable diagnostics (slow)'), Option('-J', '--no-join', default=False, action='store_true', help='Do not wait for task results'), Option('-S', '--suite', default=self.app.cyanide_suite, help='Specify test suite to execute (path to class)'), )
def get_options(self): conf = self.app.conf return (Option('-l', '--loglevel', default=conf.CELERYMON_LOG_LEVEL, action="store", dest="loglevel", help="Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL."), Option('-P', '--port', action="store", type="int", dest="http_port", default=8989, help="Port the webserver should listen to."), Option('-A', '--address', action="store", type="string", dest="http_address", default="", help="Address webserver should listen to. Default (any)."), Option('-D', '--detach', action="store_true", dest="detach", default=False, help="Run as daemon."))
def get_options(self): conf = self.app.conf return ( ( Option('-l', '--loglevel', default=conf.CELERYMON_LOG_LEVEL, help='Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL.'), Option('-P', '--port', type='int', dest='http_port', default=8989, help='Port the webserver should listen to.'), Option('-B', '--bind', dest='http_address', default='', help='Address webserver should listen to. Default (any).'), Option('-D', '--detach', action='store_true', help='Run as daemon.') ) + daemon_options('celerymon.pid') )
class apply(Command): args = "<task_name>" option_list = Command.option_list + ( Option("--args", "-a"), Option("--kwargs", "-k"), Option("--eta"), Option("--countdown", type="int"), Option("--expires"), Option("--serializer", default="json"), Option("--queue"), Option("--exchange"), Option("--routing-key"), ) def run(self, name, *_, **kw): # Positional args. args = kw.get("args") or () if isinstance(args, basestring): args = anyjson.loads(args) # Keyword args. kwargs = kw.get("kwargs") or {} if isinstance(kwargs, basestring): kwargs = anyjson.loads(kwargs) # Expires can be int/float. expires = kw.get("expires") or None try: expires = float(expires) except (TypeError, ValueError): # or a string describing an ISO 8601 datetime. try: expires = maybe_iso8601(expires) except (TypeError, ValueError): raise res = self.app.send_task(name, args=args, kwargs=kwargs, countdown=kw.get("countdown"), serializer=kw.get("serializer"), queue=kw.get("queue"), exchange=kw.get("exchange"), routing_key=kw.get("routing_key"), eta=maybe_iso8601(kw.get("eta")), expires=expires) self.out(res.id)
class result(Command): args = "<task_id>" option_list = Command.option_list + (Option("--task", "-t"), ) def run(self, task_id, *args, **kwargs): result_cls = self.app.AsyncResult task = kwargs.get("task") if task: result_cls = self.app.tasks[task].AsyncResult result = result_cls(task_id) self.out(self.prettify(result.get())[1])
def get_options(self): return ( Option('-i', '--iterations', type='int', default=50, help='Number of iterations for each test'), Option('-n', '--numtests', type='int', default=None, help='Number of tests to execute'), Option('-o', '--offset', type='int', default=0, help='Start at custom offset'), Option('--block-timeout', type='int', default=30 * 60), Option('-l', '--list', action='store_true', dest='list_all', help='List all tests'), Option('-r', '--repeat', type='float', default=0, help='Number of times to repeat the test suite'), )
def __init__(self, *args, **kwargs): self.template = kwargs.pop('template', None) super(App, self).__init__(*args, **kwargs) self.user_options['preload'].add( Option( '-Z', '--template', default='default', help='Configuration template to use: {0}'.format( template_names(), ), )) signals.user_preload_options.connect(self.on_preload_parsed) self.after_configure = None
def get_options(self): return ( Option('-d', '--dump', action='store_true'), Option('-c', '--camera'), Option('--detach', action='store_true'), Option('-F', '--frequency', '--freq', type='float', default=1.0), Option('-r', '--maxrate'), Option('-l', '--loglevel', default='INFO'), ) + daemon_options(default_pidfile='celeryev.pid')
def get_options(self): return ( Option('-d', '--dump', action="store_true"), Option('-c', '--camera'), Option('--detach', action="store_true"), Option('-F', '--frequency', '--freq', type="float", default=1.0), Option('-r', '--maxrate'), Option('-l', '--loglevel', default="INFO"), )
def __init__(self, *args, **kwargs): self.template = kwargs.pop('template', None) super(App, self).__init__(*args, **kwargs) self.user_options['preload'].add( Option( '-Z', '--template', default='default', type=str, help='Configuration template to use: {0}'.format( template_names(), ), )) signals.user_preload_options.connect(self.on_preload_parsed) if IS_CELERY_4: self.on_configure.connect(self._maybe_use_default_template)
class migrate(Command): """Migrate tasks from one broker to another. Warning: This command is experimental, make sure you have a backup of the tasks before you continue. Example: .. code-block:: console $ celery migrate amqp://A.example.com amqp://[email protected]// $ celery migrate redis://localhost amqp://guest@localhost// """ args = '<source_url> <dest_url>' option_list = Command.option_list + ( Option('--limit', '-n', type='int', help='Number of tasks to consume (int)'), Option('--timeout', '-t', type='float', default=1.0, help='Timeout in seconds (float) waiting for tasks'), Option('--ack-messages', '-a', action='store_true', help='Ack messages from source broker.'), Option('--tasks', '-T', help='List of task names to filter on.'), Option('--queues', '-Q', help='List of queues to migrate.'), Option('--forever', '-F', action='store_true', help='Continually migrate tasks until killed.'), ) progress_fmt = MIGRATE_PROGRESS_FMT def on_migrate_task(self, state, body, message): self.out(self.progress_fmt.format(state=state, body=body)) def run(self, source, destination, **kwargs): from kombu import Connection from celery.contrib.migrate import migrate_tasks migrate_tasks(Connection(source), Connection(destination), callback=self.on_migrate_task, **kwargs)
class migrate(Command): """Migrate tasks from one broker to another. Examples:: celery migrate redis://localhost amqp://guest@localhost// celery migrate django:// redis://localhost NOTE: This command is experimental, make sure you have a backup of the tasks before you continue. """ args = '<source_url> <dest_url>' option_list = Command.option_list + ( Option('--limit', '-n', type='int', help='Number of tasks to consume (int)'), Option('--timeout', '-t', type='float', default=1.0, help='Timeout in seconds (float) waiting for tasks'), Option('--ack-messages', '-a', action='store_true', help='Ack messages from source broker.'), Option('--tasks', '-T', help='List of task names to filter on.'), Option('--queues', '-Q', help='List of queues to migrate.'), Option('--forever', '-F', action='store_true', help='Continually migrate tasks until killed.'), ) progress_fmt = MIGRATE_PROGRESS_FMT def on_migrate_task(self, state, body, message): self.out(self.progress_fmt.format(state=state, body=body)) def run(self, *args, **kwargs): if len(args) != 2: # this never exits due to OptionParser.parse_options self.run_from_argv(self.prog_name, ['migrate', '--help']) raise SystemExit() from kombu import Connection from celery.contrib.migrate import migrate_tasks migrate_tasks(Connection(args[0]), Connection(args[1]), callback=self.on_migrate_task, **kwargs)
class migrate(Command): """Migrate tasks from one broker to another. Examples:: celery migrate redis://localhost amqp://guest@localhost// celery migrate django:// redis://localhost NOTE: This command is experimental, make sure you have a backup of the tasks before you continue. """ args = '<source_url> <dest_url>' option_list = Command.option_list + ( Option('--limit', '-n', type='int', help='Number of tasks to consume (int)'), Option('--timeout', '-t', type='float', default=1.0, help='Timeout in seconds (float) waiting for tasks'), Option('--ack-messages', '-a', action='store_true', help='Ack messages from source broker.'), Option('--tasks', '-T', help='List of task names to filter on.'), Option('--queues', '-Q', help='List of queues to migrate.'), Option('--forever', '-F', action='store_true', help='Continually migrate tasks until killed.'), ) def on_migrate_task(self, state, body, message): self.out('Migrating task %s/%s: %s[%s]' % (state.count, state.strtotal, body['task'], body['id'])) def run(self, *args, **kwargs): if len(args) != 2: return self.show_help('migrate') from kombu import Connection from celery.contrib.migrate import migrate_tasks migrate_tasks(Connection(args[0]), Connection(args[1]), callback=self.on_migrate_task, **kwargs)
def test_with_cmdline_config(self): cmd = MockCommand(app=self.app) cmd.enable_config_from_cmdline = True cmd.namespace = 'worker' rest = cmd.setup_app_from_commandline(argv=[ '--loglevel=INFO', '--', 'broker.url=amqp://broker.example.com', '.prefetch_multiplier=100' ]) self.assertEqual(cmd.app.conf.broker_url, 'amqp://broker.example.com') self.assertEqual(cmd.app.conf.worker_prefetch_multiplier, 100) self.assertListEqual(rest, ['--loglevel=INFO']) cmd.app = None cmd.get_app = Mock(name='get_app') cmd.get_app.return_value = self.app self.app.user_options['preload'] = [ Option('--foo', action='store_true'), ] cmd.setup_app_from_commandline(argv=[ '--foo', '--loglevel=INFO', '--', 'broker.url=amqp://broker.example.com', '.prefetch_multiplier=100' ]) self.assertIs(cmd.app, cmd.get_app())
def get_options(self): return ( Option('-d', '--dump', action="store_true", dest="dump", help="Dump events to stdout."), Option('-c', '--camera', action="store", dest="camera", help="Camera class to take event snapshots with."), Option('--detach', default=False, action="store_true", dest="detach", help="Recording: Detach and run in the background."), Option('-F', '--frequency', '--freq', action="store", dest="frequency", type="float", default=1.0, help="Recording: Snapshot frequency."), Option('-r', '--maxrate', action="store", dest="maxrate", default=None, help="Recording: Shutter rate limit (e.g. 10/m)"), Option('-l', '--loglevel', action="store", dest="loglevel", default="INFO", help="Loglevel. Default is WARNING."))
def get_options(self): return ( Option('--root', default=path(), help='Directory holding Vagrantfile.'), Option('--name', default=None, help='Optional VM name.'), Option('--provision-with', default=None, type='string', action='callback', callback=csv_list_option, help='Optional comma-separated list of provisioners.'), Option('--quiet-stdout', action='store_true', help='Disable output to stdout.'), Option('--quiet-stderr', action='store_true', help='Disable output to stderr.'), Option('--force', action='store_true', help='Force action (applies to e.g. halt).'), )
class shell(Command): # pragma: no cover """Start shell session with convenient access to celery symbols. The following symbols will be added to the main globals: - celery: the current application. - chord, group, chain, chunks, xmap, xstarmap subtask, Task - all registered tasks. Example Session: .. code-block:: bash $ celery shell >>> celery <Celery default:0x1012d9fd0> >>> add <@task: tasks.add> >>> add.delay(2, 2) <AsyncResult: 537b48c7-d6d3-427a-a24a-d1b4414035be> """ option_list = Command.option_list + ( Option('--ipython', '-I', action='store_true', dest='force_ipython', help='force iPython.'), Option('--bpython', '-B', action='store_true', dest='force_bpython', help='force bpython.'), Option('--python', '-P', action='store_true', dest='force_python', help='force default Python shell.'), Option('--without-tasks', '-T', action='store_true', help="don't add tasks to locals."), Option('--eventlet', action='store_true', help='use eventlet.'), Option('--gevent', action='store_true', help='use gevent.'), ) def run(self, force_ipython=False, force_bpython=False, force_python=False, without_tasks=False, eventlet=False, gevent=False, **kwargs): sys.path.insert(0, os.getcwd()) if eventlet: import_module('celery.concurrency.eventlet') if gevent: import_module('celery.concurrency.gevent') import celery import celery.task.base self.app.loader.import_default_modules() self.locals = { 'celery': self.app, 'Task': celery.Task, 'chord': celery.chord, 'group': celery.group, 'chain': celery.chain, 'chunks': celery.chunks, 'xmap': celery.xmap, 'xstarmap': celery.xstarmap, 'subtask': celery.subtask } if not without_tasks: self.locals.update( dict((task.__name__, task) for task in values(self.app.tasks) if not task.name.startswith('celery.'))) if force_python: return self.invoke_fallback_shell() elif force_bpython: return self.invoke_bpython_shell() elif force_ipython: return self.invoke_ipython_shell() return self.invoke_default_shell() def invoke_default_shell(self): try: import IPython # noqa except ImportError: try: import bpython # noqa except ImportError: return self.invoke_fallback_shell() else: return self.invoke_bpython_shell() else: return self.invoke_ipython_shell() def invoke_fallback_shell(self): import code try: import readline except ImportError: pass else: import rlcompleter readline.set_completer(rlcompleter.Completer(self.locals).complete) readline.parse_and_bind('tab:complete') code.interact(local=self.locals) def invoke_ipython_shell(self): try: from IPython.frontend.terminal import embed embed.TerminalInteractiveShell(user_ns=self.locals).mainloop() except ImportError: # ipython < 0.11 from IPython.Shell import IPShell IPShell(argv=[], user_ns=self.locals).mainloop() def invoke_bpython_shell(self): import bpython bpython.embed(self.locals)