17db96d56Sopenharmony_ci.. currentmodule:: asyncio
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci=======
57db96d56Sopenharmony_ciRunners
67db96d56Sopenharmony_ci=======
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_ci**Source code:** :source:`Lib/asyncio/runners.py`
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ciThis section outlines high-level asyncio primitives to run asyncio code.
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciThey are built on top of an :ref:`event loop <asyncio-event-loop>` with the aim
147db96d56Sopenharmony_cito simplify async code usage for common wide-spread scenarios.
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci.. contents::
177db96d56Sopenharmony_ci   :depth: 1
187db96d56Sopenharmony_ci   :local:
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ciRunning an asyncio Program
237db96d56Sopenharmony_ci==========================
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci.. function:: run(coro, *, debug=None)
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ci   Execute the :term:`coroutine` *coro* and return the result.
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci   This function runs the passed coroutine, taking care of
307db96d56Sopenharmony_ci   managing the asyncio event loop, *finalizing asynchronous
317db96d56Sopenharmony_ci   generators*, and closing the threadpool.
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci   This function cannot be called when another asyncio event loop is
347db96d56Sopenharmony_ci   running in the same thread.
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci   If *debug* is ``True``, the event loop will be run in debug mode. ``False`` disables
377db96d56Sopenharmony_ci   debug mode explicitly. ``None`` is used to respect the global
387db96d56Sopenharmony_ci   :ref:`asyncio-debug-mode` settings.
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci   This function always creates a new event loop and closes it at
417db96d56Sopenharmony_ci   the end.  It should be used as a main entry point for asyncio
427db96d56Sopenharmony_ci   programs, and should ideally only be called once.
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci   Example::
457db96d56Sopenharmony_ci
467db96d56Sopenharmony_ci       async def main():
477db96d56Sopenharmony_ci           await asyncio.sleep(1)
487db96d56Sopenharmony_ci           print('hello')
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci       asyncio.run(main())
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci   .. versionadded:: 3.7
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci   .. versionchanged:: 3.9
557db96d56Sopenharmony_ci      Updated to use :meth:`loop.shutdown_default_executor`.
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci   .. versionchanged:: 3.10
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci      *debug* is ``None`` by default to respect the global debug mode settings.
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci
627db96d56Sopenharmony_ciRunner context manager
637db96d56Sopenharmony_ci======================
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci.. class:: Runner(*, debug=None, loop_factory=None)
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci   A context manager that simplifies *multiple* async function calls in the same
687db96d56Sopenharmony_ci   context.
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci   Sometimes several top-level async functions should be called in the same :ref:`event
717db96d56Sopenharmony_ci   loop <asyncio-event-loop>` and :class:`contextvars.Context`.
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci   If *debug* is ``True``, the event loop will be run in debug mode. ``False`` disables
747db96d56Sopenharmony_ci   debug mode explicitly. ``None`` is used to respect the global
757db96d56Sopenharmony_ci   :ref:`asyncio-debug-mode` settings.
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_ci   *loop_factory* could be used for overriding the loop creation.
787db96d56Sopenharmony_ci   It is the responsibility of the *loop_factory* to set the created loop as the
797db96d56Sopenharmony_ci   current one. By default :func:`asyncio.new_event_loop` is used and set as
807db96d56Sopenharmony_ci   current event loop with :func:`asyncio.set_event_loop` if *loop_factory* is ``None``.
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci   Basically, :func:`asyncio.run()` example can be rewritten with the runner usage::
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci        async def main():
857db96d56Sopenharmony_ci            await asyncio.sleep(1)
867db96d56Sopenharmony_ci            print('hello')
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ci        with asyncio.Runner() as runner:
897db96d56Sopenharmony_ci            runner.run(main())
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci   .. versionadded:: 3.11
927db96d56Sopenharmony_ci
937db96d56Sopenharmony_ci   .. method:: run(coro, *, context=None)
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci      Run a :term:`coroutine <coroutine>` *coro* in the embedded loop.
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci      Return the coroutine's result or raise its exception.
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci      An optional keyword-only *context* argument allows specifying a
1007db96d56Sopenharmony_ci      custom :class:`contextvars.Context` for the *coro* to run in.
1017db96d56Sopenharmony_ci      The runner's default context is used if ``None``.
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ci      This function cannot be called when another asyncio event loop is
1047db96d56Sopenharmony_ci      running in the same thread.
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ci   .. method:: close()
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ci      Close the runner.
1097db96d56Sopenharmony_ci
1107db96d56Sopenharmony_ci      Finalize asynchronous generators, shutdown default executor, close the event loop
1117db96d56Sopenharmony_ci      and release embedded :class:`contextvars.Context`.
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci   .. method:: get_loop()
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci      Return the event loop associated with the runner instance.
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_ci   .. note::
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci      :class:`Runner` uses the lazy initialization strategy, its constructor doesn't
1207db96d56Sopenharmony_ci      initialize underlying low-level structures.
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ci      Embedded *loop* and *context* are created at the :keyword:`with` body entering
1237db96d56Sopenharmony_ci      or the first call of :meth:`run` or :meth:`get_loop`.
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci
1267db96d56Sopenharmony_ciHandling Keyboard Interruption
1277db96d56Sopenharmony_ci==============================
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_ci.. versionadded:: 3.11
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ciWhen :const:`signal.SIGINT` is raised by :kbd:`Ctrl-C`, :exc:`KeyboardInterrupt`
1327db96d56Sopenharmony_ciexception is raised in the main thread by default. However this doesn't work with
1337db96d56Sopenharmony_ci:mod:`asyncio` because it can interrupt asyncio internals and can hang the program from
1347db96d56Sopenharmony_ciexiting.
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ciTo mitigate this issue, :mod:`asyncio` handles :const:`signal.SIGINT` as follows:
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci1. :meth:`asyncio.Runner.run` installs a custom :const:`signal.SIGINT` handler before
1397db96d56Sopenharmony_ci   any user code is executed and removes it when exiting from the function.
1407db96d56Sopenharmony_ci2. The :class:`~asyncio.Runner` creates the main task for the passed coroutine for its
1417db96d56Sopenharmony_ci   execution.
1427db96d56Sopenharmony_ci3. When :const:`signal.SIGINT` is raised by :kbd:`Ctrl-C`, the custom signal handler
1437db96d56Sopenharmony_ci   cancels the main task by calling :meth:`asyncio.Task.cancel` which raises
1447db96d56Sopenharmony_ci   :exc:`asyncio.CancelledError` inside the main task.  This causes the Python stack
1457db96d56Sopenharmony_ci   to unwind, ``try/except`` and ``try/finally`` blocks can be used for resource
1467db96d56Sopenharmony_ci   cleanup.  After the main task is cancelled, :meth:`asyncio.Runner.run` raises
1477db96d56Sopenharmony_ci   :exc:`KeyboardInterrupt`.
1487db96d56Sopenharmony_ci4. A user could write a tight loop which cannot be interrupted by
1497db96d56Sopenharmony_ci   :meth:`asyncio.Task.cancel`, in which case the second following :kbd:`Ctrl-C`
1507db96d56Sopenharmony_ci   immediately raises the :exc:`KeyboardInterrupt` without cancelling the main task.
151