174 lines
4.7 KiB
Python
174 lines
4.7 KiB
Python
|
|
"""The ``celery shell`` program, used to start a REPL."""
|
||
|
|
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
from importlib import import_module
|
||
|
|
|
||
|
|
import click
|
||
|
|
|
||
|
|
from celery.bin.base import CeleryCommand, CeleryOption, handle_preload_options
|
||
|
|
|
||
|
|
|
||
|
|
def _invoke_fallback_shell(locals):
|
||
|
|
import code
|
||
|
|
try:
|
||
|
|
import readline
|
||
|
|
except ImportError:
|
||
|
|
pass
|
||
|
|
else:
|
||
|
|
import rlcompleter
|
||
|
|
readline.set_completer(
|
||
|
|
rlcompleter.Completer(locals).complete)
|
||
|
|
readline.parse_and_bind('tab:complete')
|
||
|
|
code.interact(local=locals)
|
||
|
|
|
||
|
|
|
||
|
|
def _invoke_bpython_shell(locals):
|
||
|
|
import bpython
|
||
|
|
bpython.embed(locals)
|
||
|
|
|
||
|
|
|
||
|
|
def _invoke_ipython_shell(locals):
|
||
|
|
for ip in (_ipython, _ipython_pre_10,
|
||
|
|
_ipython_terminal, _ipython_010,
|
||
|
|
_no_ipython):
|
||
|
|
try:
|
||
|
|
return ip(locals)
|
||
|
|
except ImportError:
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
def _ipython(locals):
|
||
|
|
from IPython import start_ipython
|
||
|
|
start_ipython(argv=[], user_ns=locals)
|
||
|
|
|
||
|
|
|
||
|
|
def _ipython_pre_10(locals): # pragma: no cover
|
||
|
|
from IPython.frontend.terminal.ipapp import TerminalIPythonApp
|
||
|
|
app = TerminalIPythonApp.instance()
|
||
|
|
app.initialize(argv=[])
|
||
|
|
app.shell.user_ns.update(locals)
|
||
|
|
app.start()
|
||
|
|
|
||
|
|
|
||
|
|
def _ipython_terminal(locals): # pragma: no cover
|
||
|
|
from IPython.terminal import embed
|
||
|
|
embed.TerminalInteractiveShell(user_ns=locals).mainloop()
|
||
|
|
|
||
|
|
|
||
|
|
def _ipython_010(locals): # pragma: no cover
|
||
|
|
from IPython.Shell import IPShell
|
||
|
|
IPShell(argv=[], user_ns=locals).mainloop()
|
||
|
|
|
||
|
|
|
||
|
|
def _no_ipython(self): # pragma: no cover
|
||
|
|
raise ImportError('no suitable ipython found')
|
||
|
|
|
||
|
|
|
||
|
|
def _invoke_default_shell(locals):
|
||
|
|
try:
|
||
|
|
import IPython # noqa
|
||
|
|
except ImportError:
|
||
|
|
try:
|
||
|
|
import bpython # noqa
|
||
|
|
except ImportError:
|
||
|
|
_invoke_fallback_shell(locals)
|
||
|
|
else:
|
||
|
|
_invoke_bpython_shell(locals)
|
||
|
|
else:
|
||
|
|
_invoke_ipython_shell(locals)
|
||
|
|
|
||
|
|
|
||
|
|
@click.command(cls=CeleryCommand, context_settings={
|
||
|
|
'allow_extra_args': True
|
||
|
|
})
|
||
|
|
@click.option('-I',
|
||
|
|
'--ipython',
|
||
|
|
is_flag=True,
|
||
|
|
cls=CeleryOption,
|
||
|
|
help_group="Shell Options",
|
||
|
|
help="Force IPython.")
|
||
|
|
@click.option('-B',
|
||
|
|
'--bpython',
|
||
|
|
is_flag=True,
|
||
|
|
cls=CeleryOption,
|
||
|
|
help_group="Shell Options",
|
||
|
|
help="Force bpython.")
|
||
|
|
@click.option('--python',
|
||
|
|
is_flag=True,
|
||
|
|
cls=CeleryOption,
|
||
|
|
help_group="Shell Options",
|
||
|
|
help="Force default Python shell.")
|
||
|
|
@click.option('-T',
|
||
|
|
'--without-tasks',
|
||
|
|
is_flag=True,
|
||
|
|
cls=CeleryOption,
|
||
|
|
help_group="Shell Options",
|
||
|
|
help="Don't add tasks to locals.")
|
||
|
|
@click.option('--eventlet',
|
||
|
|
is_flag=True,
|
||
|
|
cls=CeleryOption,
|
||
|
|
help_group="Shell Options",
|
||
|
|
help="Use eventlet.")
|
||
|
|
@click.option('--gevent',
|
||
|
|
is_flag=True,
|
||
|
|
cls=CeleryOption,
|
||
|
|
help_group="Shell Options",
|
||
|
|
help="Use gevent.")
|
||
|
|
@click.pass_context
|
||
|
|
@handle_preload_options
|
||
|
|
def shell(ctx, ipython=False, bpython=False,
|
||
|
|
python=False, without_tasks=False, eventlet=False,
|
||
|
|
gevent=False, **kwargs):
|
||
|
|
"""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.
|
||
|
|
"""
|
||
|
|
sys.path.insert(0, os.getcwd())
|
||
|
|
if eventlet:
|
||
|
|
import_module('celery.concurrency.eventlet')
|
||
|
|
if gevent:
|
||
|
|
import_module('celery.concurrency.gevent')
|
||
|
|
import celery
|
||
|
|
app = ctx.obj.app
|
||
|
|
app.loader.import_default_modules()
|
||
|
|
|
||
|
|
# pylint: disable=attribute-defined-outside-init
|
||
|
|
locals = {
|
||
|
|
'app': app,
|
||
|
|
'celery': 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,
|
||
|
|
'signature': celery.signature,
|
||
|
|
}
|
||
|
|
|
||
|
|
if not without_tasks:
|
||
|
|
locals.update({
|
||
|
|
task.__name__: task for task in app.tasks.values()
|
||
|
|
if not task.name.startswith('celery.')
|
||
|
|
})
|
||
|
|
|
||
|
|
if python:
|
||
|
|
_invoke_fallback_shell(locals)
|
||
|
|
elif bpython:
|
||
|
|
try:
|
||
|
|
_invoke_bpython_shell(locals)
|
||
|
|
except ImportError:
|
||
|
|
ctx.obj.echo(f'{ctx.obj.ERROR}: bpython is not installed')
|
||
|
|
elif ipython:
|
||
|
|
try:
|
||
|
|
_invoke_ipython_shell(locals)
|
||
|
|
except ImportError as e:
|
||
|
|
ctx.obj.echo(f'{ctx.obj.ERROR}: {e}')
|
||
|
|
_invoke_default_shell(locals)
|