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