Runners¶
Source code:Lib/asyncio/runners.py
This section outlines high-level asyncio primitives to run asyncio code.
They are built on top of anevent loop with the aimto simplify async code usage for common wide-spread scenarios.
Running an asyncio Program¶
- asyncio.run(coro,*,debug=None,loop_factory=None)¶
Executecoro in an asyncio event loop and return the result.
The argument can be any awaitable object.
This function runs the awaitable, taking care of managing theasyncio event loop,finalizing asynchronous generators, andclosing the executor.
This function cannot be called when another asyncio event loop isrunning in the same thread.
Ifdebug is
True
, the event loop will be run in debug mode.False
disablesdebug mode explicitly.None
is used to respect the globalDebug Mode settings.Ifloop_factory is not
None
, it is used to create a new event loop;otherwiseasyncio.new_event_loop()
is used. The loop is closed at the end.This function should be used as a main entry point for asyncio programs,and should ideally only be called once. It is recommended to useloop_factory to configure the event loop instead of policies.Passingasyncio.EventLoop
allows running asyncio without thepolicy system.The executor is given a timeout duration of 5 minutes to shutdown.If the executor hasn’t finished within that duration, a warning isemitted and the executor is closed.
Example:
asyncdefmain():awaitasyncio.sleep(1)print('hello')asyncio.run(main())
Added in version 3.7.
Άλλαξε στην έκδοση 3.9:Updated to use
loop.shutdown_default_executor()
.Άλλαξε στην έκδοση 3.10:debug is
None
by default to respect the global debug mode settings.Άλλαξε στην έκδοση 3.12:Addedloop_factory parameter.
Άλλαξε στην έκδοση 3.14:coro can be any awaitable object.
Σημείωση
The
asyncio
policy system is deprecated and will be removedin Python 3.16; from there on, an explicitloop_factory is neededto configure the event loop.
Runner context manager¶
- classasyncio.Runner(*,debug=None,loop_factory=None)¶
A context manager that simplifiesmultiple async function calls in the samecontext.
Sometimes several top-level async functions should be called in the sameeventloop and
contextvars.Context
.Ifdebug is
True
, the event loop will be run in debug mode.False
disablesdebug mode explicitly.None
is used to respect the globalDebug Mode settings.loop_factory could be used for overriding the loop creation.It is the responsibility of theloop_factory to set the created loop as thecurrent one. By default
asyncio.new_event_loop()
is used and set ascurrent event loop withasyncio.set_event_loop()
ifloop_factory isNone
.Basically,
asyncio.run()
example can be rewritten with the runner usage:asyncdefmain():awaitasyncio.sleep(1)print('hello')withasyncio.Runner()asrunner:runner.run(main())
Added in version 3.11.
- run(coro,*,context=None)¶
Executecoro in the embedded event loop.
The argument can be any awaitable object.
If the argument is a coroutine, it is wrapped in a Task.
An optional keyword-onlycontext argument allows specifying acustom
contextvars.Context
for the code to run in.The runner’s default context is used if context isNone
.Returns the awaitable’s result or raises an exception.
This function cannot be called when another asyncio event loop isrunning in the same thread.
Άλλαξε στην έκδοση 3.14:coro can be any awaitable object.
- close()¶
Close the runner.
Finalize asynchronous generators, shutdown default executor, close the event loopand release embedded
contextvars.Context
.
- get_loop()¶
Return the event loop associated with the runner instance.
Σημείωση
Runner
uses the lazy initialization strategy, its constructor doesn’tinitialize underlying low-level structures.Embeddedloop andcontext are created at the
with
body enteringor the first call ofrun()
orget_loop()
.
Handling Keyboard Interruption¶
Added in version 3.11.
Whensignal.SIGINT
is raised byCtrl-C,KeyboardInterrupt
exception is raised in the main thread by default. However this doesn’t work withasyncio
because it can interrupt asyncio internals and can hang the program fromexiting.
To mitigate this issue,asyncio
handlessignal.SIGINT
as follows:
asyncio.Runner.run()
installs a customsignal.SIGINT
handler beforeany user code is executed and removes it when exiting from the function.The
Runner
creates the main task for the passed coroutine for itsexecution.When
signal.SIGINT
is raised byCtrl-C, the custom signal handlercancels the main task by callingasyncio.Task.cancel()
which raisesasyncio.CancelledError
inside the main task. This causes the Python stackto unwind,try/except
andtry/finally
blocks can be used for resourcecleanup. After the main task is cancelled,asyncio.Runner.run()
raisesKeyboardInterrupt
.A user could write a tight loop which cannot be interrupted by
asyncio.Task.cancel()
, in which case the second followingCtrl-Cimmediately raises theKeyboardInterrupt
without cancelling the main task.