Utilities for multithreaded applications with Click¶
The Thread class¶
-
class
click_threading.
Thread
(*args, **kwargs)¶ A thread that automatically pushes the parent thread’s context in the new thread.
Since version 5.0, click maintains global stacks of context objects. The topmost context on that stack can be accessed with
get_current_context()
.There is one stack for each Python thread. That means if you are in the main thread (where you can use
get_current_context()
just fine) and spawn athreading.Thread
, that thread won’t be able to access the same context usingget_current_context()
.Thread
is a subclass ofthreading.Thread
that preserves the current thread context when spawning a new one, by pushing it on the stack of the new thread as well.
Output and prompts from multiple threads¶
-
class
click_threading.
UiWorker
¶ A worker-queue system to manage and synchronize output and prompts from other threads.
>>> import click >>> from click_threading import UiWorker, Thread, get_ui_worker >>> ui = UiWorker() # on main thread >>> def target(): ... click.echo("Hello world!") ... get_ui_worker().shutdown() ... >>> >>> @click.command() ... def cli(): ... with ui.patch_click(): ... t = Thread(target=target) ... t.start() ... ui.run() >>> runner = click.testing.CliRunner() >>> result = runner.invoke(cli, []) >>> assert result.output.strip() == 'Hello world!'
Using this class instead of just spawning threads brings a few advantages:
- If one thread prompts for input, other output from other threads is
queued until the
click.prompt()
call returns. - If you call echo with a multiline-string, it is guaranteed that this string is not interleaved with other output.
Disadvantages:
- The main thread is used for the output (using any other thread produces
weird behavior with interrupts).
ui.run()
in the above example blocks untilui.shutdown()
is called.
- If one thread prompts for input, other output from other threads is
queued until the