Перейти к содержимому

Event loopЦикл событий

Исходный код: Lib/asyncio/events.py, Lib/asyncio/base_events.py


Предисловие

Цикл событий является ядром любого приложения asyncio. Циклы событий выполняют асинхронные задачи и колбэки, осуществляют сетевые операции ввода-вывода и запускают подпроцессы.

Разработчики приложений обычно должны использовать высокоуровневые функции asyncio, такие как asyncio.run(), и редко нуждаются в обращении к объекту цикла событий или вызове его методов. Этот раздел предназначен в основном для авторов низкоуровневого кода, библиотек и фреймворков, которым требуется более тонкий контроль над поведением цикла событий.

Получение цикла событий

Следующие низкоуровневые функции могут использоваться для получения, установки или создания цикла событий:

asyncio.get_running_loop()

Возвращает запущенный цикл событий в текущем потоке ОС.

Вызывает RuntimeError, если нет запущенного цикла событий.

Эта функция может быть вызвана только из корутины или колбэка.

Добавлено в версии 3.7.

asyncio.get_event_loop()

Возвращает текущий цикл событий.

При вызове из корутины или колбэка (например, запланированного с помощью call_soon или аналогичного API), эта функция всегда возвращает запущенный цикл событий.

Если запущенный цикл событий не установлен, функция возвращает результат вызова get_event_loop_policy().get_event_loop().

Поскольку эта функция имеет довольно сложное поведение (особенно при использовании пользовательских политик цикла событий), предпочтительнее использовать функцию get_running_loop(), а не get_event_loop() в корутинах и колбэках.

Как отмечено выше, рассмотрите использование высокоуровневой функции asyncio.run() вместо использования этих низкоуровневых функций для ручного создания и закрытия цикла событий.

Изменено в версии 3.14: Вызывает RuntimeError, если нет текущего цикла событий.

Примечание

Система политик asyncio устарела и будет удалена в Python 3.16; начиная с этой версии, эта функция будет возвращать текущий запущенный цикл событий, если он есть, иначе она вернет цикл, установленный set_event_loop().

asyncio.set_event_loop(loop)

Устанавливает loop в качестве текущего цикла событий для текущего потока ОС.

asyncio.new_event_loop()

Создает и возвращает новый объект цикла событий.

Обратите внимание, что поведение функций get_event_loop(), set_event_loop(), и new_event_loop() может быть изменено настройкой пользовательской политики цикла событий.

Содержание

Эта страница документации содержит следующие разделы:

Event loop methodsМетоды цикла событий

Циклы событий имеют низкоуровневые API для следующих целей:

Running and stopping the loopЗапуск и остановка цикла

loop.run_until_complete(future)

Выполняется до тех пор, пока future (экземпляр Future) не будет завершён.

Если аргументом является объект корутины, то он неявно планируется к выполнению в виде asyncio.Task.

Возвращает результат Future или возбуждает его исключение.

loop.run_forever()

Выполняет цикл событий до тех пор, пока не будет вызван stop().

Если stop() вызывается до вызова run_forever(), цикл один раз опросит I/O-селектор с нулевым тайм-аутом, выполнит все колбэки, запланированные в ответ на I/O-события (а также те, что уже были запланированы), и затем завершится.

Если stop() вызывается во время работы run_forever(), цикл выполнит текущую порцию колбэков и затем завершится. Обратите внимание, что новые колбэки, запланированные другими колбэками, в этом случае не выполнятся; вместо этого они будут выполнены при следующем вызове run_forever() или run_until_complete().

loop.stop()

Останавливает цикл событий.

loop.is_running()

Возвращает True, если цикл событий в данный момент выполняется.

loop.is_closed()

Возвращает True, если цикл событий был закрыт.

loop.close()

Закрывает цикл событий.

Цикл не должен выполняться при вызове этой функции. Все ожидающие колбэки будут отброшены.

Этот метод очищает все очереди и завершает работу исполнителя, но не ожидает его окончания.

Этот метод идемпотентен и необратим. Никакие другие методы не должны вызываться после закрытия цикла событий.

async loop.shutdown_asyncgens()

Планирует закрытие всех открытых в данный момент объектов асинхронный генератор с помощью вызова aclose(). После вызова этого метода цикл событий будет выдавать предупреждение, если будет произведена итерация нового асинхронного генератора. Это следует использовать для надёжного завершения всех запланированных асинхронных генераторов.

Обратите внимание, что нет необходимости вызывать эту функцию, когда используется asyncio.run().

Пример:

python
try:
    loop.run_forever()
finally:
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()

Добавлено в версии 3.6.

async loop.shutdown_default_executor(timeout=None)

Планирует закрытие исполнителя по умолчанию и ожидает его присоединения ко всем потокам в ThreadPoolExecutor. После вызова этого метода использование исполнителя по умолчанию с loop.run_in_executor() вызовет исключение RuntimeError.

Параметр timeout задаёт количество времени (в float секундах), которое будет предоставлено исполнителю для завершения присоединения. По умолчанию, None, исполнителю разрешается неограниченное количество времени.

Если значение timeout достигнуто, выбрасывается RuntimeWarning, и исполнитель по умолчанию завершается без ожидания присоединения его потоков.

Примечание

Не вызывайте этот метод при использовании asyncio.run(), поскольку последний обрабатывает завершение исполнителя по умолчанию автоматически.

Добавлено в версии 3.9.

Изменено в версии 3.12: Добавлен параметр timeout.

Scheduling callbacksПланирование колбэков

loop.call_soon(callback, *args, context=None)

Планирует вызов колбэка колбэк с аргументами args на следующей итерации цикла событий.

Возвращает экземпляр asyncio.Handle, который можно использовать позже для отмены колбэка.

Колбэки вызываются в том порядке, в котором они были зарегистрированы. Каждый колбэк будет вызван ровно один раз.

Необязательный аргумент context (только по ключу) задаёт пользовательский contextvars.Context для выполнения колбэка. Колбэки используют текущий контекст, если context не указан.

В отличие от call_soon_threadsafe(), этот метод не является потокобезопасным.

loop.call_soon_threadsafe(callback, *args, context=None)

Потокобезопасный вариант call_soon(). При планировании колбэков из другого потока эта функция должна использоваться, поскольку call_soon() не является потокобезопасной.

Эту функцию безопасно вызывать из реентерабельного контекста или обработчика сигналов, однако небезопасно и нецелесообразно использовать возвращаемый дескриптор в таких контекстах.

Вызывает RuntimeError, если вызван на закрытом цикле. Это может произойти во вторичном потоке при завершении основного приложения.

Смотрите раздел concurrency and multithreading документации.

Изменено в версии 3.7: Был добавлен именованный параметр context. Подробнее см. PEP 567.

Примечание

Большинство функций планирования asyncio не допускают передачи именованных аргументов. Для этого используйте functools.partial():

python
# запланирует "print("Hello", flush=True)"
loop.call_soon(
    functools.partial(print, "Hello", flush=True))

Использование частичных объектов (partial) обычно удобнее, чем лямбда-функций, поскольку asyncio может лучше отображать частичные объекты в отладочных и ошибочных сообщениях.

Scheduling delayed callbacksПланирование отложенных колбэков

Цикл событий предоставляет механизмы для планирования функций обратного вызова, которые будут вызваны в некоторый момент в будущем. Цикл событий использует монотонные часы для отслеживания времени.

loop.call_later(delay, callback, *args, context=None)

Планирует вызов колбэк через заданное количество секунд delay (может быть int или float).

Возвращается экземпляр asyncio.TimerHandle, который можно использовать для отмены колбэка.

колбэк будет вызван ровно один раз. Если два колбэка запланированы на одно и то же время, порядок их вызова не определён.

Необязательные позиционные args будут переданы колбэку при его вызове. Используйте functools.partial() для передачи именованных аргументов в колбэк.

Необязательный именованный аргумент context позволяет указать пользовательский contextvars.Context для выполнения колбэк. Если context не указан, используется текущий контекст.

Примечание

В целях производительности колбэки, запланированные с помощью loop.call_later(), могут выполняться с опережением до одного такта часов (см. time.get_clock_info('monotonic').resolution).

Изменено в версии 3.7: Был добавлен именованный параметр context. Подробнее см. PEP 567.

Изменено в версии 3.8: В Python 3.7 и более ранних версиях с реализацией цикла событий по умолчанию delay не мог превышать один день. Это было исправлено в Python 3.8.

loop.call_at(when, callback, *args, context=None)

Планирует вызов колбэк в указанную абсолютную временную метку when (int или float), используя ту же временную привязку, что и loop.time().

Поведение этого метода аналогично call_later().

Возвращается экземпляр asyncio.TimerHandle, который можно использовать для отмены колбэка.

Примечание

В целях производительности колбэки, запланированные с помощью loop.call_at(), могут выполняться с опережением до одного такта часов (см. time.get_clock_info('monotonic').resolution).

Изменено в версии 3.7: Был добавлен именованный параметр context. Подробнее см. PEP 567.

Изменено в версии 3.8: В Python 3.7 и более ранних версиях с реализацией цикла событий по умолчанию разница между when и текущим временем не могла превышать один день. Это было исправлено в Python 3.8.

loop.time()

Возвращает текущее время в виде значения float в соответствии с внутренними монотонными часами цикла событий.

Примечание

Изменено в версии 3.8: В Python 3.7 и более ранних версиях таймауты (относительный delay или абсолютный when) не должны были превышать один день. Это было исправлено в Python 3.8.

Смотрите также

Функция asyncio.sleep().

Creating futures and tasksСоздание future и задач

loop.create_future()

Создаёт объект asyncio.Future, прикреплённый к циклу событий.

Это предпочтительный способ создания Future в asyncio. Это позволяет сторонним циклам событий предоставлять альтернативные реализации объекта Future (с более высокой производительностью или инструментарием).

Добавлено в версии 3.5.2.

loop.create_task(coro, *, name=None, context=None, eager_start=None, **kwargs)

Планирует выполнение корутины coro. Возвращает объект Task.

Сторонние циклы событий могут использовать свой собственный подкласс Task для обеспечения совместимости. В этом случае тип результата является подклассом Task.

Полная сигнатура функции в значительной степени совпадает с сигнатурой конструктора Task (или фабрики) – все ключевые аргументы этой функции передаются этому интерфейсу.

Если аргумент name указан и не равен None, он устанавливается в качестве имени задачи с помощью Task.set_name().

Необязательный аргумент, передаваемый только по ключу, context позволяет указать пользовательский contextvars.Context для выполнения coro. Копия текущего контекста создаётся, если context не предоставлен.

Необязательный аргумент, передаваемый только по ключу, eager_start позволяет указать, должна ли задача выполняться немедленно при вызове create_task или быть запланированной на потом. Если eager_start не передан, будет использоваться режим, установленный loop.set_task_factory().

Изменено в версии 3.8: Добавлен параметр name.

Изменено в версии 3.11: Добавлен параметр context.

Изменено в версии 3.13.3: Добавлен kwargs, который передаёт произвольные дополнительные параметры, включая name и context.

Изменено в версии 3.13.4: Отменено изменение, которое передавало name и context (если он равен None), при этом другие произвольные ключевые аргументы по-прежнему передаются (чтобы не нарушать обратную совместимость с версией 3.13.3).

Изменено в версии 3.14: Все kwargs теперь передаются. Параметр eager_start работает с немедленными фабриками задач.

loop.set_task_factory(factory)

Устанавливает фабрику задач, которая будет использоваться loop.create_task().

Если factory равен None, будет установлена фабрика задач по умолчанию. В противном случае factory должен быть callable с сигнатурой, соответствующей (loop, coro, **kwargs), где loop – ссылка на активный цикл событий, а coro – объект корутины. Вызываемый объект должен передавать все kwargs и возвращать объект, совместимый с asyncio.Task.

Изменено в версии 3.13.3: Требуется, чтобы все kwargs передавались asyncio.Task.

Изменено в версии 3.13.4: name больше не передаётся фабрикам задач. context больше не передаётся фабрикам задач, если он равен None.

Изменено в версии 3.14: name и context теперь снова безусловно передаются фабрикам задач.

loop.get_task_factory()

Возвращает фабрику задач или None, если используется фабрика по умолчанию.

Opening network connectionsОткрытие сетевых соединений

async loop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, happy_eyeballs_delay=None, interleave=None, all_errors=False)

Открывает потоковое транспортное соединение по указанному адресу, заданному host и port.

Семейство сокетов может быть либо AF_INET, либо AF_INET6 в зависимости от host (или аргумента family, если он указан).

Тип сокета будет SOCK_STREAM.

protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола asyncio.

Этот метод пытается установить соединение в фоновом режиме. При успехе он возвращает пару (transport, protocol).

Хронологическая сводка нижележащей операции выглядит следующим образом:

  1. Соединение устанавливается, и для него создаётся транспорт.

  2. protocol_factory вызывается без аргументов и должен вернуть экземпляр протокола.

  3. Экземпляр протокола связывается с транспортом вызовом его метода connection_made().

  4. В случае успеха возвращается кортеж (transport, protocol).

Созданный транспорт представляет собой зависящий от реализации двунаправленный поток.

Другие аргументы:

  • ssl: если указан и не равен false, создаётся SSL/TLS транспорт (по умолчанию создаётся обычный TCP транспорт). Если ssl является объектом ssl.SSLContext, этот контекст используется для создания транспорта; если ssl равен True, используется контекст по умолчанию, возвращаемый ssl.create_default_context().

  • server_hostname устанавливает или переопределяет имя хоста, с которым будет сверяться сертификат целевого сервера. Должен передаваться только в том случае, если ssl не равен None. По умолчанию используется значение аргумента host. Если host пуст, значение по умолчанию отсутствует, и необходимо передать значение для server_hostname. Если server_hostname – пустая строка, проверка имени хоста отключается (что является серьезным риском безопасности, допускающим возможные атаки типа «человек посередине»).

  • family, proto, flags – это необязательные семейство адресов, протокол и флаги, передаваемые в getaddrinfo() для разрешения host. Если заданы, все они должны быть целыми числами из соответствующих констант модуля socket.

  • happy_eyeballs_delay, если задан, включает алгоритм Happy Eyeballs для данного соединения. Он должен быть числом с плавающей запятой, представляющим время в секундах ожидания завершения попытки соединения, прежде чем начать следующую попытку параллельно. Это «Задержка попытки соединения», как определено в RFC 8305. Разумное значение по умолчанию, рекомендованное RFC, равно 0.25 (250 миллисекунд).

  • interleave управляет переупорядочиванием адресов, когда имя хоста разрешается в несколько IP-адресов. Если 0 или не указан, переупорядочивание не производится, и адреса испытываются в порядке, возвращаемом getaddrinfo(). Если указано положительное целое число, адреса перемежаются по семейству адресов, и заданное целое число интерпретируется как «Количество первого семейства адресов», как определено в RFC 8305. Значение по умолчанию равно 0, если happy_eyeballs_delay не указан, и 1, если указан.

  • sock, если задан, должен быть существующим, уже подключенным объектом socket.socket, который будет использоваться транспортом. Если задан sock, ни один из параметров host, port, family, proto, flags, happy_eyeballs_delay, interleave и local_addr не должен указываться.

    Примечание

    Аргумент sock передаёт владение сокетом созданному транспорту. Чтобы закрыть сокет, вызовите метод close() транспорта.

  • local_addr, если задан, представляет собой кортеж (local_host, local_port), используемый для локальной привязки сокета. local_host и local_port разрешаются с помощью getaddrinfo(), аналогично host и port.

  • ssl_handshake_timeout (для TLS-соединения) – время в секундах ожидания завершения рукопожатия TLS перед прерыванием соединения. 60.0 секунд, если None (по умолчанию).

  • ssl_shutdown_timeout – это время в секундах ожидания завершения SSL-завершения перед разрывом соединения. 30.0 секунд, если None (по умолчанию).

  • all_errors определяет, какие исключения возбуждаются, когда не удается создать соединение. По умолчанию возбуждается только одно Exception: первое исключение, если исключение только одно или все ошибки имеют одинаковое сообщение, или одно OSError с объединенными сообщениями об ошибках. Если all_errors равно True, будет возбуждено ExceptionGroup, содержащее все исключения (даже если исключение только одно).

Изменено в версии 3.5: Добавлена поддержка SSL/TLS в ProactorEventLoop.

Изменено в версии 3.6: Параметр сокета socket.TCP_NODELAY по умолчанию устанавливается для всех TCP-соединений.

Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout.

Изменено в версии 3.8: Добавлены параметры happy_eyeballs_delay и interleave.

Алгоритм Happy Eyeballs: успех с dual-stack хостами. Когда IPv4-путь и протокол сервера работают, а IPv6-путь и протокол не работают, клиентское приложение с dual-stack испытывает значительную задержку соединения по сравнению с клиентом, использующим только IPv4. Это нежелательно, так как ухудшает пользовательский опыт для dual-stack клиента. В данном документе определены требования к алгоритмам, уменьшающим эту видимую пользователем задержку, и представлен алгоритм.

Для получения дополнительной информации: https://datatracker.ietf.org/doc/html/rfc6555

Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.

Изменено в версии 3.12: Добавлен all_errors.

Смотрите также

Функция open_connection() представляет собой высокоуровневый альтернативный API. Она возвращает пару (StreamReader, StreamWriter), которая может использоваться непосредственно в коде async/await.

async loop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_port=None, allow_broadcast=None, sock=None)

Создать дейтаграммное соединение.

Семейство сокетов может быть либо AF_INET, AF_INET6, или AF_UNIX, в зависимости от host (или аргумента family, если он указан).

Тип сокета будет SOCK_DGRAM.

protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола.

В случае успеха возвращается кортеж из (transport, protocol).

Другие аргументы:

  • local_addr, если задан, представляет собой кортеж (local_host, local_port), используемый для локальной привязки сокета. local_host и local_port разрешаются с помощью getaddrinfo().

    Примечание

    В Windows при использовании проакторного цикла событий с local_addr=None будет возбуждено OSError с errno.WSAEINVAL при его выполнении.

  • remote_addr, если задан, представляет собой кортеж (remote_host, remote_port), используемый для подключения сокета к удалённому адресу. remote_host и remote_port разрешаются с помощью getaddrinfo().

  • family, proto, flags – необязательные семейство адресов, протокол и флаги, которые будут переданы в getaddrinfo() для разрешения host. Если заданы, все они должны быть целыми числами из соответствующих констант модуля socket.

  • reuse_port указывает ядру разрешить привязку этой конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Эта опция не поддерживается в Windows и некоторых Unix-системах. Если константа socket.SO_REUSEPORT не определена, то такая возможность не поддерживается.

  • allow_broadcast указывает ядру разрешить этой конечной точке отправлять сообщения на широковещательный адрес.

  • sock может быть опционально указан для использования предварительно созданного, уже подключённого объекта socket.socket, который будет использоваться транспортом. Если указан, local_addr и remote_addr должны быть опущены (должны быть None).

    Примечание

    Аргумент sock передаёт владение сокетом созданному транспорту. Чтобы закрыть сокет, вызовите метод close() транспорта.

См. примеры протокола эхо-клиента UDP и протокола эхо-сервера UDP.

Изменено в версии 3.4.4: Были добавлены параметры family, proto, flags, reuse_address, reuse_port, allow_broadcast и sock.

Изменено в версии 3.8: Добавлена поддержка Windows.

Изменено в версии 3.8.1: Параметр reuse_address больше не поддерживается, так как использование socket.SO_REUSEADDR представляет серьёзную угрозу безопасности для UDP. Явная передача reuse_address=True приведёт к возбуждению исключения.

Когда несколько процессов с разными UID назначают сокеты на один и тот же адрес UDP-сокета с SO_REUSEADDR, входящие пакеты могут случайным образом распределяться между сокетами.

На поддерживаемых платформах reuse_port может использоваться как замена аналогичной функциональности. С reuse_port вместо этого используется socket.SO_REUSEPORT, что специально предотвращает назначение сокетов с разными UID на один и тот же адрес сокета.

Изменено в версии 3.11: Параметр reuse_address, отключённый начиная с Python 3.8.1, 3.7.6 и 3.6.10, был полностью удалён.

async loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)

Создаёт соединение Unix.

Семейство сокетов будет AF_UNIX; тип сокета будет SOCK_STREAM.

В случае успеха возвращается кортеж из (transport, protocol).

path – это имя сокета домена Unix, оно обязательно, если не указан параметр sock. Поддерживаются абстрактные сокеты Unix, пути str, bytes и Path.

См. документацию метода loop.create_connection() для получения информации об аргументах этого метода.

Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout. Параметр path теперь может быть объектом, подобным пути.

Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.

Creating network serversСоздание сетевых серверов

async loop.create_server(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, keep_alive=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True)

Создаёт TCP-сервер (тип сокета SOCK_STREAM), прослушивающий порт port адреса host.

Возвращает объект Server.

Аргументы:

  • protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола.

  • Параметр host может быть задан несколькими типами, которые определяют, где будет прослушивать сервер:

    • Если host является строкой, TCP-сервер привязывается к одному сетевому интерфейсу, указанному в host.

    • Если host является последовательностью строк, TCP-сервер будет привязан ко всем сетевым интерфейсам, указанным этой последовательностью.

    • Если host является пустой строкой или None, подразумеваются все интерфейсы, и будет возвращён список из нескольких сокетов (скорее всего, один для IPv4 и один для IPv6).

  • Параметр port можно задать для указания порта, на котором сервер должен прослушивать. Если 0 или None (по умолчанию), будет выбран случайный неиспользуемый порт (обратите внимание, что если host разрешается в несколько сетевых интерфейсов, для каждого интерфейса будет выбран разный случайный порт).

  • Параметр family можно установить в socket.AF_INET или AF_INET6, чтобы заставить сокет использовать IPv4 или IPv6. Если не задан, family будет определён по имени хоста (по умолчанию AF_UNSPEC).

  • flags – это битовая маска для getaddrinfo().

  • Параметр sock может быть указан опционально для использования уже существующего объекта сокета. Если он указан, host и port не должны быть заданы.

    Примечание

    Аргумент sock передаёт право владения сокетом созданному серверу. Чтобы закрыть сокет, вызовите метод close() сервера.

  • backlog – это максимальное количество соединений в очереди, передаваемых в listen() (по умолчанию 100).

  • Параметр ssl можно установить в экземпляр SSLContext для включения TLS поверх принимаемых соединений.

  • Параметр reuse_address указывает ядру повторно использовать локальный сокет в состоянии TIME_WAIT, не дожидаясь истечения его естественного тайм-аута. Если не указан, будет автоматически установлен в True на Unix.

  • Параметр reuse_port указывает ядру разрешить привязку этой конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Этот параметр не поддерживается в Windows.

  • Параметр keep_alive, установленный в True, поддерживает активность соединений, включая периодическую передачу сообщений.

Изменено в версии 3.13: Добавлен параметр keep_alive.

  • Параметр ssl_handshake_timeout (для TLS-сервера) – это время в секундах ожидания завершения TLS-рукопожатия перед прерыванием соединения. 60.0 секунд, если None (по умолчанию).

  • ssl_shutdown_timeout – это время в секундах ожидания завершения SSL-завершения перед разрывом соединения. 30.0 секунд, если None (по умолчанию).

  • Параметр start_serving, установленный в True (по умолчанию), заставляет созданный сервер немедленно начать приём соединений. Если установлен в False, пользователь должен выполнить await на Server.start_serving() или Server.serve_forever(), чтобы сервер начал приём соединений.

Изменено в версии 3.5: Добавлена поддержка SSL/TLS в ProactorEventLoop.

Изменено в версии 3.5.1: Параметр host может быть последовательностью строк.

Изменено в версии 3.6: Добавлены параметры ssl_handshake_timeout и start_serving. Параметр сокета socket.TCP_NODELAY теперь устанавливается по умолчанию для всех TCP-соединений.

Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.

Смотрите также

Функция start_server() – это альтернативный API более высокого уровня, который возвращает пару из StreamReader и StreamWriter, которые можно использовать в асинхронном коде с async/await.

async loop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True, cleanup_socket=True)

Аналогично loop.create_server(), но работает с семейством сокетов AF_UNIX.

Параметр path – это имя сокета домена Unix, и он обязателен, если не указан аргумент sock. Поддерживаются абстрактные сокеты Unix, пути str, bytes и Path.

Если cleanup_socket равен true, то сокет Unix будет автоматически удалён из файловой системы при закрытии сервера, если только сокет не был заменён после создания сервера.

См. документацию метода loop.create_server() для получения информации об аргументах этого метода.

Изменено в версии 3.7: Добавлены параметры ssl_handshake_timeout и start_serving. Параметр path теперь может быть объектом Path.

Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.

Изменено в версии 3.13: Добавлен параметр cleanup_socket.

async loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)

Оборачивает уже принятое соединение в пару транспорт/протокол.

Этот метод может использоваться серверами, которые принимают соединения за пределами asyncio, но используют asyncio для их обработки.

Параметры:

  • protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола.

  • sock – это существующий объект сокета, возвращённый из socket.accept.

    Примечание

    Аргумент sock передаёт владение сокетом созданному транспорту. Чтобы закрыть сокет, вызовите метод close() транспорта.

  • ssl может быть установлен в SSLContext для включения SSL поверх принятых соединений.

  • ssl_handshake_timeout – это время в секундах ожидания завершения SSL-рукопожатия перед прерыванием соединения. 60.0 секунд, если None (по умолчанию).

  • ssl_shutdown_timeout – это время в секундах ожидания завершения SSL-завершения перед разрывом соединения. 30.0 секунд, если None (по умолчанию).

Возвращает пару (transport, protocol).

Добавлено в версии 3.5.3.

Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout.

Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.

Transferring filesПередача файлов

async loop.sendfile(transport, file, offset=0, count=None, *, fallback=True)

Отправить file через транспорт. Возвращает общее количество отправленных байт.

Метод использует высокопроизводительный os.sendfile(), если доступен.

file должен быть обычным файловым объектом, открытым в бинарном режиме.

offset указывает, откуда начинать чтение файла. Если указан, count – это общее количество байт для передачи, в отличие от отправки файла до достижения EOF. Позиция в файле всегда обновляется, даже если этот метод вызывает ошибку, и file.tell() можно использовать для получения фактического количества отправленных байт.

fallback, установленный в True, заставляет asyncio вручную читать и отправлять файл, когда платформа не поддерживает системный вызов sendfile (например, Windows или SSL-сокет на Unix).

Вызывает SendfileNotAvailableError, если система не поддерживает системный вызов sendfile и fallback равен False.

Добавлено в версии 3.7.

TLS upgradeОбновление TLS

async loop.start_tls(transport, protocol, sslcontext, *, server_side=False, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)

Обновить существующее соединение на основе транспорта до TLS.

Создать экземпляр кодировщика/декодировщика TLS и вставить его между транспорт и протокол. Кодировщик/декодировщик реализует как транспорт-ориентированный протокол, так и протокол-ориентированный транспорт.

Возвращает созданный экземпляр с двумя интерфейсами. После await, протокол должен прекратить использование исходного транспорт и общаться только с возвращённым объектом, потому что кодировщик кэширует данные со стороны протокол и время от времени обменивается дополнительными пакетами TLS-сессии с транспорт.

В некоторых ситуациях (например, когда переданный транспорт уже закрывается) это может вернуть None.

Параметры:

  • Экземпляры транспорт и протокол, которые возвращают такие методы, как create_server() и create_connection().

  • sslcontext: настроенный экземпляр SSLContext.

  • server_side передавайте True, когда соединение на стороне сервера обновляется (как соединение, созданное с помощью create_server()).

  • server_hostname: устанавливает или переопределяет имя хоста, с которым будет сопоставляться сертификат целевого сервера.

  • ssl_handshake_timeout – это (для TLS-соединения) время в секундах ожидания завершения рукопожатия TLS перед разрывом соединения. 60.0 секунд, если None (по умолчанию).

  • ssl_shutdown_timeout – это время в секундах ожидания завершения SSL-завершения перед разрывом соединения. 30.0 секунд, если None (по умолчанию).

Добавлено в версии 3.7.

Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.

Watching file descriptorsНаблюдение за файловыми дескрипторами

loop.add_reader(fd, callback, *args)

Начать наблюдение за файловым дескриптором fd на доступность чтения и вызвать колбэк с указанными аргументами, когда fd станет доступен для чтения.

Любой ранее существовавший колбэк, зарегистрированный для fd, отменяется и заменяется на колбэк.

loop.remove_reader(fd)

Прекратить наблюдение за файловым дескриптором fd на доступность чтения. Возвращает True, если fd ранее наблюдался для чтения.

loop.add_writer(fd, callback, *args)

Начать наблюдение за файловым дескриптором fd на доступность записи и вызвать колбэк с указанными аргументами args, когда fd станет доступен для записи.

Любой ранее существовавший колбэк, зарегистрированный для fd, отменяется и заменяется на колбэк.

Используйте functools.partial() для передачи именованных аргументов в колбэк.

loop.remove_writer(fd)

Прекратить наблюдение за файловым дескриптором fd на доступность записи. Возвращает True, если fd ранее наблюдался для записи.

См. также раздел Platform Support о некоторых ограничениях этих методов.

Working with socket objects directlyРабота с сокетными объектами напрямую

В целом, реализации протоколов, использующие API на основе транспорта, такие как loop.create_connection() и loop.create_server(), быстрее реализаций, работающих с сокетами напрямую. Однако существуют сценарии, когда производительность не критична, и работа с объектами socket напрямую более удобна.

async loop.sock_recv(sock, nbytes)

Получить до nbytes байт из sock. Асинхронная версия socket.recv().

Возвращает полученные данные в виде объекта bytes.

sock должен быть неблокирующим сокетом.

Изменено в версии 3.7: Хотя этот метод всегда документировался как корутинный, релизы до Python 3.7 возвращали Future. Начиная с Python 3.7 это метод async def.

async loop.sock_recv_into(sock, buf)

Получить данные из sock в буфер buf. Создана по образцу блокирующего метода socket.recv_into().

Возвращает количество байт, записанных в буфер.

sock должен быть неблокирующим сокетом.

Добавлено в версии 3.7.

async loop.sock_recvfrom(sock, bufsize)

Получает датаграмму размером до bufsize из sock. Асинхронная версия socket.recvfrom().

Возвращает кортеж (полученные данные, удалённый адрес).

sock должен быть неблокирующим сокетом.

Добавлено в версии 3.11.

async loop.sock_recvfrom_into(sock, buf, nbytes=0)

Получает датаграмму размером до nbytes из sock в buf. Асинхронная версия socket.recvfrom_into().

Возвращает кортеж (количество полученных байтов, удалённый адрес).

sock должен быть неблокирующим сокетом.

Добавлено в версии 3.11.

async loop.sock_sendall(sock, data)

Отправляет data в сокет sock. Асинхронная версия socket.sendall().

Этот метод продолжает отправку в сокет до тех пор, пока все данные в data не будут отправлены или не возникнет ошибка. В случае успеха возвращается None. При ошибке возбуждается исключение. Кроме того, нет способа определить, сколько данных (если они были) было успешно обработано принимающей стороной соединения.

sock должен быть неблокирующим сокетом.

Изменено в версии 3.7: Несмотря на то, что метод всегда документировался как корутинный, до Python 3.7 он возвращал Future. Начиная с Python 3.7, это метод async def.

async loop.sock_sendto(sock, data, address)

Отправляет датаграмму из sock в address. Асинхронная версия socket.sendto().

Возвращает количество отправленных байтов.

sock должен быть неблокирующим сокетом.

Добавлено в версии 3.11.

async loop.sock_connect(sock, address)

Подключает sock к удалённому сокету по адресу address.

Асинхронная версия socket.connect().

sock должен быть неблокирующим сокетом.

Изменено в версии 3.5.2: address больше не нужно разрешать. sock_connect попытается проверить, разрешён ли уже address, вызвав socket.inet_pton(). Если нет, loop.getaddrinfo() будет использоваться для разрешения address.

Смотрите также

loop.create_connection() и asyncio.open_connection().

async loop.sock_accept(sock)

Принимает соединение. Создано по образцу блокирующего метода socket.accept().

Сокет должен быть привязан к адресу и ожидать соединений. Возвращаемое значение – пара (conn, address), где conn является новым объектом сокета, который можно использовать для отправки и получения данных по соединению, а address – адрес, привязанный к сокету на другом конце соединения.

sock должен быть неблокирующим сокетом.

Изменено в версии 3.7: Несмотря на то, что метод всегда документировался как корутинный, до Python 3.7 он возвращал Future. Начиная с Python 3.7, это метод async def.

Смотрите также

loop.create_server() и start_server().

async loop.sock_sendfile(sock, file, offset=0, count=None, *, fallback=True)

Отправляет файл с использованием высокопроизводительного os.sendfile, если это возможно. Возвращает общее количество отправленных байт.

Асинхронная версия socket.sendfile().

sock должен быть неблокирующим socket.SOCK_STREAM socket.

file должен быть обычным файловым объектом, открытым в бинарном режиме.

offset указывает, откуда начинать чтение файла. Если указан, count – это общее количество байт для передачи, в отличие от отправки файла до достижения EOF. Позиция в файле всегда обновляется, даже если этот метод вызывает ошибку, и file.tell() можно использовать для получения фактического количества отправленных байт.

fallback, если установлено в True, заставляет asyncio вручную читать и отправлять файл, когда платформа не поддерживает системный вызов sendfile (например, Windows или SSL-сокет на Unix).

Возбуждает SendfileNotAvailableError, если система не поддерживает системный вызов sendfile и fallback равен False.

sock должен быть неблокирующим сокетом.

Добавлено в версии 3.7.

DNS

async loop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0)

Асинхронная версия socket.getaddrinfo().

async loop.getnameinfo(sockaddr, flags=0)

Асинхронная версия socket.getnameinfo().

Примечание

Оба метода getaddrinfo и getnameinfo внутренне используют свои синхронные версии через исполнитель пула потоков цикла событий по умолчанию. Когда этот исполнитель перегружен, эти методы могут испытывать задержки, которые библиотеки более высокого уровня могут сообщать как увеличенные тайм-ауты. Чтобы смягчить это, рассмотрите возможность использования пользовательского исполнителя для других задач пользователя, или установки исполнителя по умолчанию с большим количеством рабочих потоков.

Изменено в версии 3.7: Оба метода getaddrinfo и getnameinfo всегда документировались как возвращающие корутину, но до Python 3.7 они на самом деле возвращали объекты asyncio.Future. Начиная с Python 3.7 оба метода являются корутинами.

Working with pipesРабота с каналами

async loop.connect_read_pipe(protocol_factory, pipe)

Регистрирует читающий конец pipe в цикле событий.

protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола asyncio.

pipe является файлоподобным объектом.

Возвращает пару (transport, protocol), где транспорт поддерживает интерфейс ReadTransport, а протокол является объектом, созданным protocol_factory.

В SelectorEventLoop цикле событий канал устанавливается в неблокирующий режим.

async loop.connect_write_pipe(protocol_factory, pipe)

Регистрирует записывающий конец pipe в цикле событий.

protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола asyncio.

pipe является файлоподобным объектом.

Возвращает пару (transport, protocol), где транспорт поддерживает интерфейс WriteTransport, а протокол является объектом, созданным protocol_factory.

В SelectorEventLoop цикле событий канал устанавливается в неблокирующий режим.

Примечание

SelectorEventLoop не поддерживает вышеуказанные методы в Windows. Используйте ProactorEventLoop вместо этого для Windows.

Смотрите также

Методы loop.subprocess_exec() и loop.subprocess_shell().

Unix signalsСигналы Unix

loop.add_signal_handler(signum, callback, *args)

Устанавливает колбэк в качестве обработчика сигнала signum, передавая аргументы в качестве позиционных аргументов.

loop будет вызывать колбэк вместе с другими поставленными в очередь колбэками и выполняемыми корутинами этого цикла событий. В отличие от обработчиков сигналов, зарегистрированных с помощью signal.signal(), колбэк, зарегистрированный этой функцией, может взаимодействовать с циклом событий.

Вызывает ValueError, если номер сигнала недействителен или не может быть перехвачен. Вызывает RuntimeError, если возникла проблема при настройке обработчика.

Используйте functools.partial() для передачи именованных аргументов в колбэк.

Как и signal.signal(), эта функция должна вызываться в главном потоке.

loop.remove_signal_handler(sig)

Удаляет обработчик сигнала sig.

Возвращает True, если обработчик сигнала был удалён, или False, если для данного сигнала не был установлен обработчик.

Смотрите также

Модуль signal.

Executing code in thread or process poolsВыполнение кода в пулах потоков или процессов

awaitable loop.run_in_executor(executor, func, *args)

Организует вызов func в указанном исполнителе с передачей args в качестве позиционных аргументов.

Аргумент исполнитель должен быть экземпляром concurrent.futures.Executor. Исполнитель по умолчанию используется, если исполнитель равен None. Исполнитель по умолчанию может быть установлен с помощью loop.set_default_executor(), в противном случае будет лениво инициализирован concurrent.futures.ThreadPoolExecutor и использован run_in_executor() при необходимости.

Пример:

python
import asyncio
import concurrent.futures

def blocking_io():
    # Файловые операции (например, логирование) могут блокировать
    # цикл событий: выполняйте их в пуле потоков.
    with open('/dev/urandom', 'rb') as f:
        return f.read(100)

def cpu_bound():
    # Операции, связанные с CPU, заблокируют цикл событий:
    # в целом предпочтительнее выполнять их в
    # пуле процессов.
    return sum(i * i for i in range(10 ** 7))

async def main():
    loop = asyncio.get_running_loop()

    ## Варианты:

    # 1. Выполнить в исполнителе цикла по умолчанию:
    result = await loop.run_in_executor(
        None, blocking_io)
    print('default thread pool', result)

    # 2. Выполнить в пользовательском пуле потоков:
    with concurrent.futures.ThreadPoolExecutor() as pool:
        result = await loop.run_in_executor(
            pool, blocking_io)
        print('custom thread pool', result)

    # 3. Выполнить в пользовательском пуле процессов:
    with concurrent.futures.ProcessPoolExecutor() as pool:
        result = await loop.run_in_executor(
            pool, cpu_bound)
        print('custom process pool', result)

    # 4. Запустить в пользовательском пуле интерпретаторов:
    with concurrent.futures.InterpreterPoolExecutor() as pool:
        result = await loop.run_in_executor(
            pool, cpu_bound)
        print('custom interpreter pool', result)

if __name__ == '__main__':
    asyncio.run(main())

Обратите внимание, что для варианта 3 требуется защита точки входа (if __name__ == '__main__') из-за особенностей multiprocessing, которая используется ProcessPoolExecutor. См. Безопасный импорт главного модуля.

Этот метод возвращает объект asyncio.Future.

Используйте functools.partial() для передачи именованных аргументов в func.

Изменено в версии 3.5.3: loop.run_in_executor() больше не настраивает max_workers создаваемого им исполнителя пула потоков, вместо этого оставляя исполнителю пула потоков (ThreadPoolExecutor) установку значения по умолчанию.

loop.set_default_executor(executor)

Устанавливает исполнитель в качестве исполнителя по умолчанию, используемого run_in_executor(). исполнитель должен быть экземпляром ThreadPoolExecutor, который включает InterpreterPoolExecutor.

Изменено в версии 3.11: исполнитель должен быть экземпляром ThreadPoolExecutor.

Error handling APIAPI обработки ошибок

Позволяет настраивать обработку исключений в цикле событий.

loop.set_exception_handler(handler)

Устанавливает обработчик в качестве нового обработчика исключений цикла событий.

Если обработчик равен None, будет установлен обработчик исключений по умолчанию. В противном случае обработчик должен быть вызываемым объектом с сигнатурой, соответствующей (loop, context), где loop является ссылкой на активный цикл событий, а context является объектом dict, содержащим сведения об исключении (см. документацию call_exception_handler() для получения подробной информации о контексте).

Если обработчик вызывается от имени Task или Handle, он выполняется в contextvars.Context этой задачи или дескриптора колбэка.

Изменено в версии 3.12: Обработчик может быть вызван в Context задачи или дескриптора, где возникло исключение.

loop.get_exception_handler()

Возвращает текущий обработчик исключений или None, если не был установлен пользовательский обработчик исключений.

Добавлено в версии 3.5.2.

loop.default_exception_handler(context)

Обработчик исключений по умолчанию.

Вызывается, когда возникает исключение и не установлен обработчик исключений. Может вызываться пользовательским обработчиком исключений, который хочет делегировать выполнение обработчику по умолчанию.

Параметр context имеет то же значение, что и в call_exception_handler().

loop.call_exception_handler(context)

Вызывает текущий обработчик исключений цикла событий.

context является объектом dict, содержащим следующие ключи (в будущих версиях Python могут быть добавлены новые ключи):

  • ‘message’: сообщение об ошибке;

  • 'исключение' (опционально): объект исключения;

  • ‘future’ (опционально): экземпляр asyncio.Future;

  • 'задача' (опционально): экземпляр asyncio.Task;

  • ‘handle’ (опционально): экземпляр asyncio.Handle;

  • 'протокол' (опционально): экземпляр Protocol;

  • 'транспорт' (опционально): экземпляр Transport;

  • ‘socket’ (опционально): экземпляр socket.socket;

  • ‘source_traceback’ (опционально): трассировка источника;

  • ‘handle_traceback’ (опционально): трассировка дескриптора;

  • ‘asyncgen’ (опционально): асинхронный генератор, вызвавший

    исключение.

Примечание

Этот метод не должен переопределяться в подклассах циклов событий. Для пользовательской обработки исключений используйте метод set_exception_handler().

Enabling debug modeВключение режима отладки

loop.get_debug()

Получает режим отладки (bool) цикла событий.

Значением по умолчанию является True, если переменная окружения PYTHONASYNCIODEBUG установлена в непустую строку, False в противном случае.

loop.set_debug(enabled: bool)

Устанавливает режим отладки цикла событий.

Изменено в версии 3.7: Новый режим разработки Python теперь также можно использовать для включения режима отладки.

loop.slow_callback_duration

Этот атрибут можно использовать для установки минимальной продолжительности выполнения в секундах, которая считается «медленной». Когда режим отладки включен, «медленные» колбэки регистрируются в журнале.

Значение по умолчанию – 100 миллисекунд.

Смотрите также

Режим отладки asyncio.

Running subprocessesЗапуск подпроцессов

Методы, описанные в этом подразделе, являются низкоуровневыми. В обычном асинхронном коде с async/await рассмотрите возможность использования высокоуровневых удобных функций asyncio.create_subprocess_shell() и asyncio.create_subprocess_exec() вместо них.

Примечание

В Windows цикл событий по умолчанию ProactorEventLoop поддерживает подпроцессы, тогда как SelectorEventLoop – нет. Подробнее см. Поддержка подпроцессов в Windows.

async loop.subprocess_exec(protocol_factory, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)

Создаёт подпроцесс из одной или нескольких строковых аргументов, заданных args.

args должен быть списком строк, представленных как:

Первая строка указывает исполняемый файл программы, а остальные строки задают аргументы. Вместе строковые аргументы образуют argv программы.

Это похоже на класс subprocess.Popen стандартной библиотеки, вызванный с shell=False и списком строк, переданным в качестве первого аргумента; однако там, где Popen принимает один аргумент – список строк, subprocess_exec принимает несколько строковых аргументов.

protocol_factory должен быть вызываемым объектом, возвращающим подкласс класса asyncio.SubprocessProtocol.

Другие параметры:

  • stdin может быть одним из следующих:

    • объект, похожий на файл

    • существующий файловый дескриптор (положительное целое число), например, созданный с помощью os.pipe()

    • константа subprocess.PIPE (по умолчанию), которая создаст новый канал и подключит его,

    • значение None, которое заставит подпроцесс наследовать файловый дескриптор от этого процесса

    • константа subprocess.DEVNULL, которая указывает, что будет использоваться специальный файл os.devnull

  • stdout может быть одним из следующих:

    • объект, похожий на файл

    • константа subprocess.PIPE (по умолчанию), которая создаст новый канал и подключит его,

    • значение None, которое заставит подпроцесс наследовать файловый дескриптор от этого процесса

    • константа subprocess.DEVNULL, которая указывает, что будет использоваться специальный файл os.devnull

  • stderr может принимать одно из следующих значений:

    • объект, похожий на файл

    • константа subprocess.PIPE (по умолчанию), которая создаст новый канал и подключит его,

    • значение None, которое заставит подпроцесс наследовать файловый дескриптор от этого процесса

    • константа subprocess.DEVNULL, которая указывает, что будет использоваться специальный файл os.devnull

    • константа subprocess.STDOUT, которая соединит стандартный поток ошибок с потоком стандартного вывода процесса

  • Все остальные именованные аргументы передаются в subprocess.Popen без интерпретации, за исключением bufsize, universal_newlines, shell, text, encoding и errors, которые не должны указываться вовсе.

    API подпроцесса asyncio не поддерживает декодирование потоков как текст. bytes.decode() можно использовать для преобразования байтов, возвращаемых из потока, в текст.

Если объект, похожий на файл, переданный как stdin, stdout или stderr, представляет собой канал, то другая сторона этого канала должна быть зарегистрирована с помощью connect_write_pipe() или connect_read_pipe() для использования с циклом событий.

Смотрите конструктор класса subprocess.Popen для документации по другим аргументам.

Возвращает пару (transport, protocol), где транспорт соответствует базовому классу asyncio.SubprocessTransport, а протокол – объект, созданный protocol_factory.

Если транспорт закрыт или собран сборщиком мусора, дочерний процесс уничтожается, если он все еще выполняется.

async loop.subprocess_shell(protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)

Создает подпроцесс из cmd, который может быть строкой str или bytes, закодированной в кодировку файловой системы, используя синтаксис оболочки платформы.

Это аналогично классу subprocess.Popen из стандартной библиотеки, вызываемому с shell=True.

protocol_factory должен быть вызываемым объектом, возвращающим подкласс класса SubprocessProtocol.

Смотрите subprocess_exec() для получения более подробной информации об остальных аргументах.

Возвращает пару (transport, protocol), где транспорт соответствует базовому классу SubprocessTransport, а протокол – объект, созданный protocol_factory.

Если транспорт закрыт или собран сборщиком мусора, дочерний процесс уничтожается, если он все еще выполняется.

Примечание

Ответственность приложения заключается в том, чтобы обеспечить правильное экранирование всех пробелов и специальных символов для предотвращения уязвимостей внедрения команд оболочки. Функция shlex.quote() может использоваться для правильного экранирования пробелов и специальных символов в строках, которые будут использоваться для построения команд оболочки.

Callback handlesДескрипторы колбэков

class asyncio.Handle

Объект-обёртка колбэка, возвращаемый loop.call_soon(), loop.call_soon_threadsafe().

get_context()

Возвращает объект contextvars.Context, связанный с дескриптором.

Добавлено в версии 3.12.

cancel()

Отменяет колбэк. Если колбэк уже был отменён или выполнен, этот метод не имеет эффекта.

cancelled()

Возвращает True, если колбэк был отменён.

Добавлено в версии 3.7.

class asyncio.TimerHandle

Объект-обёртка для колбэка, возвращаемый loop.call_later(), и loop.call_at().

Этот класс является подклассом Handle.

when()

Возвращает запланированное время колбэка в float секундах.

Время является абсолютной временной меткой, использующей ту же временную привязку, что и loop.time().

Добавлено в версии 3.7.

Server objectsОбъекты Server

Объекты Server создаются функциями loop.create_server(), loop.create_unix_server(), start_server() и start_unix_server().

Не создавайте экземпляр класса Server напрямую.

class asyncio.Server

Объекты Server являются асинхронными контекстными менеджерами. При использовании в инструкции async with гарантируется, что объект Server будет закрыт и не будет принимать новые соединения после завершения инструкции async with:

python
srv = await loop.create_server(...)

async with srv:
    # некоторый код

# На данный момент srv закрыт и больше не принимает новые подключения.

Изменено в версии 3.7: Объект Server является асинхронным контекстным менеджером, начиная с Python 3.7.

Изменено в версии 3.11: Этот класс был сделан общедоступным как asyncio.Server в Python 3.9.11, 3.10.3 и 3.11.

close()

Прекратить обслуживание: закрыть прослушивающие сокеты и установить атрибут sockets в None.

Сокеты, представляющие существующие входящие клиентские соединения, остаются открытыми.

Сервер закрывается асинхронно; используйте корутину wait_closed(), чтобы дождаться закрытия сервера (и отсутствия активных соединений).

close_clients()

Закрыть все существующие входящие клиентские соединения.

Вызывает close() на всех связанных транспортах.

close() следует вызывать перед close_clients() при закрытии сервера, чтобы избежать состояний гонки с новыми подключающимися клиентами.

Добавлено в версии 3.13.

abort_clients()

Немедленно закрыть все существующие входящие клиентские соединения, не дожидаясь завершения ожидающих операций.

Вызывает abort() на всех связанных транспортах.

close() следует вызывать перед abort_clients() при закрытии сервера, чтобы избежать состояний гонки с новыми подключающимися клиентами.

Добавлено в версии 3.13.

get_loop()

Возвращает цикл событий, связанный с объектом сервера.

Добавлено в версии 3.7.

async start_serving()

Начать принимать соединения.

Этот метод идемпотентен, поэтому его можно вызывать, когда сервер уже обслуживает.

Параметр start_serving, передаваемый только по ключевому слову, в loop.create_server() и asyncio.start_server() позволяет создать объект Server, который изначально не принимает соединения. В этом случае Server.start_serving() или Server.serve_forever() можно использовать, чтобы заставить Server начать принимать соединения.

Добавлено в версии 3.7.

async serve_forever()

Начать принимать соединения до тех пор, пока корутина не будет отменена. Отмена задачи serve_forever приводит к закрытию сервера.

Этот метод можно вызывать, если сервер уже принимает соединения. Для одного объекта Server может существовать только одна задача serve_forever.

Пример:

python
async def client_connected(reader, writer):
    # Общайтесь с клиентом через
    # потоки чтения/записи. Например:
    await reader.readline()

async def main(host, port):
    srv = await asyncio.start_server(
        client_connected, host, port)
    await srv.serve_forever()

asyncio.run(main('127.0.0.1', 0))

Добавлено в версии 3.7.

is_serving()

Возвращает True, если сервер принимает новые соединения.

Добавлено в версии 3.7.

async wait_closed()

Ожидать завершения метода close() и завершения всех активных соединений.

sockets

Список объектов, подобных сокетам, asyncio.trsock.TransportSocket, которые прослушивает сервер.

Изменено в версии 3.7: До Python 3.7 Server.sockets возвращал внутренний список серверных сокетов напрямую. В версии 3.7 возвращается копия этого списка.

Event loop implementationsРеализации цикла событий

asyncio поставляется с двумя различными реализациями цикла событий: SelectorEventLoop и ProactorEventLoop.

По умолчанию asyncio настроено на использование EventLoop.

class asyncio.SelectorEventLoop

Подкласс AbstractEventLoop, основанный на модуле selectors.

Использует наиболее эффективный selector, доступный для данной платформы. Также можно вручную настроить конкретную реализацию селектора для использования:

python
import asyncio
import selectors

async def main():
   ...

loop_factory = lambda: asyncio.SelectorEventLoop(selectors.SelectSelector())
asyncio.run(main(), loop_factory=loop_factory)

Доступность: Unix, Windows.

class asyncio.ProactorEventLoop

Подкласс AbstractEventLoop для Windows, использующий «I/O Completion Ports» (IOCP).

class asyncio.EventLoop

Псевдоним наиболее эффективного доступного подкласса AbstractEventLoop для данной платформы.

Это псевдоним SelectorEventLoop на Unix и ProactorEventLoop на Windows.

Добавлено в версии 3.13.

class asyncio.AbstractEventLoop

Абстрактный базовый класс для циклов событий, совместимых с asyncio.

Раздел Методы цикла событий перечисляет все методы, которые должна определить альтернативная реализация AbstractEventLoop.

ExamplesПримеры

Обратите внимание, что все примеры в этом разделе намеренно показывают, как использовать низкоуровневые API цикла событий, такие как loop.run_forever() и loop.call_soon(). Современные приложения asyncio редко нуждаются в такой записи; рассмотрите использование высокоуровневых функций, таких как asyncio.run().

Hello World with call_soon) (Hello World с call_soon()

Пример использования метода loop.call_soon() для планирования колбэка. Колбэк выводит "Hello World", а затем останавливает цикл событий:

python
import asyncio

def hello_world(loop):
    """Колбэк для вывода 'Hello World' и остановки цикла событий"""
    print('Hello World')
    loop.stop()

loop = asyncio.new_event_loop()

# Запланировать вызов hello_world()
loop.call_soon(hello_world, loop)

# Блокирующий вызов, прерванный loop.stop()
try:
    loop.run_forever()
finally:
    loop.close()

Смотрите также

Аналогичный Hello World пример, созданный с помощью корутины и функции run().

Display the current date with call_later) (Отображение текущей даты с помощью call_later()

Пример колбэка, отображающего текущую дату каждую секунду. Колбэк использует метод loop.call_later() для повторного планирования себя через 5 секунд, а затем останавливает цикл событий:

python
import asyncio
import datetime as dt

def display_date(end_time, loop):
    print(dt.datetime.now())
    if (loop.time() + 1.0) < end_time:
        loop.call_later(1, display_date, end_time, loop)
    else:
        loop.stop()

loop = asyncio.new_event_loop()

# Запланировать первый вызов display_date()
end_time = loop.time() + 5.0
loop.call_soon(display_date, end_time, loop)

# Блокирующий вызов, прерванный loop.stop()
try:
    loop.run_forever()
finally:
    loop.close()

Смотрите также

Аналогичный текущая дата пример, созданный с помощью корутины и функции run().

Watch a file descriptor for read eventsНаблюдение за файловым дескриптором на предмет событий чтения

Ожидание, пока файловый дескриптор не получит некоторые данные, с помощью метода loop.add_reader(), а затем закрытие цикла событий:

python
import asyncio
from socket import socketpair

# Создать пару связанных файловых дескрипторов
rsock, wsock = socketpair()

loop = asyncio.new_event_loop()

def reader():
    data = rsock.recv(100)
    print("Received:", data.decode())

    # Мы закончили: отменить регистрацию файлового дескриптора
    loop.remove_reader(rsock)

    # Остановить цикл событий
    loop.stop()

# Зарегистрировать файловый дескриптор для события чтения
loop.add_reader(rsock, reader)

# Симулировать приём данных из сети
loop.call_soon(wsock.send, 'abc'.encode())

try:
    # Запустить цикл событий
    loop.run_forever()
finally:
    # Мы закончили. Закрыть сокеты и цикл событий.
    rsock.close()
    wsock.close()
    loop.close()

Смотрите также

Set signal handlers for SIGINT and SIGTERMУстановка обработчиков сигналов для SIGINT и SIGTERM

(Этот signal пример работает только в Unix.)

Регистрация обработчиков для сигналов SIGINT и SIGTERM с помощью метода loop.add_signal_handler():

python
import asyncio
import functools
import os
import signal

def ask_exit(signame, loop):
    print("got signal %s: exit" % signame)
    loop.stop()

async def main():
    loop = asyncio.get_running_loop()

    for signame in {'SIGINT', 'SIGTERM'}:
        loop.add_signal_handler(
            getattr(signal, signame),
            functools.partial(ask_exit, signame, loop))

    await asyncio.sleep(3600)

print("Event loop running for 1 hour, press Ctrl+C to interrupt.")
print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")

asyncio.run(main())