Laço de Eventos
***************

**Código-fonte:** Lib/asyncio/events.py, Lib/asyncio/base_events.py

======================================================================

-[ Prefácio ]-

O laço de eventos é o núcleo de toda aplicação asyncio. Laços de
eventos executam tarefas e funções de retorno assíncronas, realizam
operações de entrada e saída e executam subprocessos.

Os desenvolvedores de aplicação normalmente devem usar as funções
asyncio de alto nível, como "asyncio.run()", e devem raramente
precisar fazer referência ao objeto de loop ou chamar seus métodos.
Esta seção destina-se principalmente a autores de código de baixo
nível, bibliotecas e frameworks, que precisam de um controle mais
preciso sobre o comportamento do laço de evento.

-[ Obtendo o laço de eventos ]-

As seguintes funções baixo nível podem ser usadas para obter, definir,
ou criar um laço de eventos:

asyncio.get_running_loop()

   Retorna o laço de eventos em execução na thread atual do sistema
   operacional.

   Levanta uma "RuntimeError" se não houver nenhum laço de eventos em
   execução.

   Esta função só pode ser chamada a partir de uma corrotina ou de um
   retorno de chamada.

   Novo na versão 3.7.

asyncio.get_event_loop()

   Obtém o laço de eventos atual.

   Quando chamada de uma corrotina ou função de retorno (por exemplo,
   agendada com call_soon ou API semelhante), esta função sempre
   retornará o laço de eventos em execução.

   Se não houver nenhum laço de eventos em execução definido, a função
   retornará o resultado da chamada
   "get_event_loop_policy().get_event_loop()".

   Devido ao fato desta função ter um comportamento particularmente
   complexo (especialmente quando políticas de laço de eventos
   customizadas estão sendo usadas), usar a função
   "get_running_loop()" é preferido ao invés de "get_event_loop()" em
   corrotinas e funções de retorno.

   Como observado acima, considere usar também a função de alto nível
   "asyncio.run()" ao invés de usar funções de baixo nível para
   manualmente criar e fechar um laço de eventos.

   Nota:

     In Python versions 3.10.0--3.10.8 and 3.11.0 this function (and
     other functions which use it implicitly) emitted a
     "DeprecationWarning" if there was no running event loop, even if
     the current loop was set on the policy. In Python versions
     3.10.9, 3.11.1 and 3.12 they emit a "DeprecationWarning" if there
     is no running event loop and no current loop is set. In some
     future Python release this will become an error.

asyncio.set_event_loop(loop)

   Define *loop* como o laço de eventos atual para a thread atual do
   sistema operacional.

asyncio.new_event_loop()

   Cria e retorna um novo objeto de laço de eventos.

Perceba que o comportamento das funções "get_event_loop()",
"set_event_loop()", e "new_event_loop()" podem ser alteradas definindo
uma política de laço de eventos customizada.

-[ Conteúdo ]-

Esta página de documentação contém as seguintes seções:

* A seção Métodos do laço de eventos é a documentação de referência
  das APIs de laço de eventos;

* A seção Tratadores de função de retorno documenta as instâncias das
  classes "Handle" e "TimerHandle", que são retornadas por métodos de
  agendamento tais como "loop.call_soon()" e "loop.call_later()";

* A seção Objetos Server documenta tipos retornados a partir de
  métodos de laço de eventos, como "loop.create_server()";

* A seção Implementações do Laço de Eventos documenta as classes
  "SelectorEventLoop" e "ProactorEventLoop";

* A seção Exemplos demonstra como trabalhar com algumas APIs do laço
  de eventos APIs.


Métodos do laço de eventos
==========================

Laços de eventos possuem APIs de **baixo nível** para as seguintes
situações:

* Executar e interromper o laço

* Agendando funções de retorno

* Agendando funções de retorno atrasadas

* Criando Futures e Tasks

* Abrindo conexões de rede

* Criando servidores de rede

* Transferindo arquivos

* Atualizando TLS

* Observando descritores de arquivo

* Trabalhando com objetos soquete diretamente

* DNS

* Trabalhando com encadeamentos

* Sinais Unix

* Executando código em conjuntos de threads ou processos

* Tratando erros da API

* Habilitando o modo de debug

* Executando Subprocessos


Executar e interromper o laço
-----------------------------

loop.run_until_complete(future)

   Executar até que o *future* (uma instância da classe "Future") seja
   completada.

   Se o argumento é um objeto corrotina, ele é implicitamente agendado
   para executar como uma "asyncio.Task".

   Retorna o resultado do Future ou levanta sua exceção.

loop.run_forever()

   Executa o laço de eventos até que "stop()" seja chamado.

   Se "stop()" for chamado antes que "run_forever()" seja chamado, o
   laço  irá pesquisar o seletor de E/S uma vez com um tempo limite de
   zero, executar todas as funções de retorno agendadas na resposta de
   eventos de E/S (e aqueles que já estavam agendados), e então sair.

   Se "stop()" for chamado enquanto "run_forever()" estiver
   executando, o laço irá executar o lote atual de funções de retorno
   e então sair. Perceba que novas funções de retorno agendadas por
   funções de retorno não serão executadas neste caso; ao invés disso,
   elas serão executadas na próxima vez que "run_forever()" ou
   "run_until_complete()" forem chamadas.

loop.stop()

   Para o laço de eventos.

loop.is_running()

   Retorna "True" se o laço de eventos estiver em execução.

loop.is_closed()

   Retorna "True" se o laço de eventos foi fechado.

loop.close()

   Fecha o laço de eventos.

   O laço não deve estar em execução quando esta função for chamada.
   Qualquer função de retorno pendente será descartada.

   Este método limpa todas as filas e desliga o executor, mas não
   aguarda pelo encerramento do executor.

   Este método é idempotente e irreversível. Nenhum outro método deve
   ser chamado depois que o laço de eventos esteja fechado.

coroutine loop.shutdown_asyncgens()

   Agenda todos os objetos *geradores assíncronos* atualmente abertos
   para serem fechados com uma chamada "aclose()". Após chamar este
   método, o laço de eventos emitirá um aviso se um novo gerador
   assíncrono for iterado. Isso deve ser utilizado para finalizar  de
   forma confiável todos os geradores assíncronos agendados.

   Perceba que não é necessário chamar esta função quando
   "asyncio.run()" for usado.

   Exemplo:

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

   Novo na versão 3.6.

coroutine loop.shutdown_default_executor()

   Agenda o encerramento do executor padrão e aguarda ele se juntar a
   todas as threads no "ThreadPoolExecutor". Uma vez que este método
   tenha sido chamado, usar o executor padrão com
   "loop.run_in_executor()" levantará um "RuntimeError".

   Nota:

     Do not call this method when using "asyncio.run()", as the latter
     handles default executor shutdown automatically.

   Novo na versão 3.9.


Agendando funções de retorno
----------------------------

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

   Agenda a *função de retorno* *callback* para ser chamada com
   argumentos *args* na próxima iteração do laço de eventos.

   Return an instance of "asyncio.Handle", which can be used later to
   cancel the callback.

   Funções de retorno são chamadas na ordem em que elas foram
   registradas. Cada função de retorno será chamada exatamente uma
   vez.

   The optional keyword-only *context* argument specifies a custom
   "contextvars.Context" for the *callback* to run in. Callbacks use
   the current context when no *context* is provided.

   Unlike "call_soon_threadsafe()", this method is not thread-safe.

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

   A thread-safe variant of "call_soon()". When scheduling callbacks
   from another thread, this function *must* be used, since
   "call_soon()" is not thread-safe.

   Levanta "RuntimeError" se chamado em um laço que já foi fechado.
   Isto pode acontecer em uma thread secundária quando a aplicação
   principal estiver desligando.

   Veja a seção concorrência e multithreading da documentação.

   Alterado na versão 3.7: O parâmetro somente-nomeado *context* foi
   adicionado. Veja **PEP 567** para mais detalhes.

Nota:

  Maior parte das funções de agendamento "asyncio" não permite passar
  argumentos nomeados. Para fazer isso, use "functools.partial()":

     # will schedule "print("Hello", flush=True)"
     loop.call_soon(
         functools.partial(print, "Hello", flush=True))

  Usar objetos parciais é usualmente mais conveniente que usar
  lambdas, pois asyncio pode renderizar objetos parciais melhor
  durante debug e mensagens de erro.


Agendando funções de retorno atrasadas
--------------------------------------

Laço de eventos fornece mecanismos para agendar funções de retorno
para serem chamadas em algum ponto no futuro. Laço de eventos usa
relógios monotônico para acompanhar o tempo.

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

   Agenda *callback* para ser chamada após o *delay* número de
   segundos fornecido (pode ser um inteiro ou um ponto flutuante).

   Uma instância de "asyncio.TimerHandle" é retornada, a qual pode ser
   usada para cancelar a função de retorno.

   *callback* será chamada exatamente uma vez. Se duas funções de
   retorno são agendadas para exatamente o mesmo tempo, a ordem na
   qual elas são chamadas é indefinida.

   O *args* posicional opcional será passado para a função de retorno
   quando ela for chamada. Se você quiser que a função de retorno seja
   chamada com argumentos nomeados, use "functools.partial()".

   Um argumento opcional somente-nomeado *context* permite especificar
   um "contextvars.Context" customizado para executar na *função de
   retorno*. O contexto atual é usado quando nenhum *context* é
   fornecido.

   Alterado na versão 3.7: O parâmetro somente-nomeado *context* foi
   adicionado. Veja **PEP 567** para mais detalhes.

   Alterado na versão 3.8: No Python 3.7 e anterior, com a
   implementação padrão do laço de eventos, o *delay* não poderia
   exceder um dia. Isto foi ajustado no Python 3.8.

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

   Agenda *callback* para ser chamada no timestamp absoluto fornecido
   *when* (um inteiro ou um ponto flutuante), usando o mesmo horário
   de referência que "loop.time()".

   O comportamento deste método é o mesmo que "call_later()".

   Uma instância de "asyncio.TimerHandle" é retornada, a qual pode ser
   usada para cancelar a função de retorno.

   Alterado na versão 3.7: O parâmetro somente-nomeado *context* foi
   adicionado. Veja **PEP 567** para mais detalhes.

   Alterado na versão 3.8: No Python 3.7 e anterior, com a
   implementação padrão do laço de eventos, a diferença entre *when* e
   o horário atual não poderia exceder um dia. Isto foi ajustado no
   Python 3.8.

loop.time()

   Retorna o horário atual, como um valor "float", de acordo com o
   relógio monotônico interno do laço de eventos.

Nota:

  Alterado na versão 3.8: No Python 3.7 e anterior, tempos limites
  (*delay* relativo ou *when* absoluto) não poderiam exceder um dia.
  Isto foi ajustado no Python 3.8.

Ver também: A função "asyncio.sleep()".


Criando Futures e Tasks
-----------------------

loop.create_future()

   Cria um objeto "asyncio.Future" atachado ao laço de eventos.

   Este é o modo preferido para criar Futures em asyncio. Isto permite
   que laços de eventos de terceiros forneçam implementações
   alternativas do objeto Future (com melhor desempenho ou
   instrumentação).

   Novo na versão 3.5.2.

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

   Schedule the execution of coroutine *coro*. Return a "Task" object.

   Laços de eventos de terceiros podem usar suas próprias subclasses
   de "Task" para interoperabilidade. Neste caso, o tipo do resultado
   é uma subclasse de "Task".

   Se o argumento *name* for fornecido e não é "None", ele é definido
   como o nome da tarefa, usando "Task.set_name()".

   An optional keyword-only *context* argument allows specifying a
   custom "contextvars.Context" for the *coro* to run in. The current
   context copy is created when no *context* is provided.

   Alterado na versão 3.8: Adicionado o parâmetro *name*.

   Alterado na versão 3.11: Adicionado o parâmetro *context*.

loop.set_task_factory(factory)

   Define a factory da tarefa que será usada por "loop.create_task()".

   If *factory* is "None" the default task factory will be set.
   Otherwise, *factory* must be a *callable* with the signature
   matching "(loop, coro, context=None)", where *loop* is a reference
   to the active event loop, and *coro* is a coroutine object.  The
   callable must return a "asyncio.Future"-compatible object.

loop.get_task_factory()

   Retorna uma factory de tarefa ou "None" se a factory padrão estiver
   em uso.


Abrindo conexões de rede
------------------------

coroutine 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)

   Abre uma conexão de transporte para streaming, para um endereço
   fornecido, especificado por *host* e *port*.

   The socket family can be either "AF_INET" or "AF_INET6" depending
   on *host* (or the *family* argument, if provided).

   The socket type will be "SOCK_STREAM".

   *protocol_factory* deve ser um chamável que retorne uma
   implementação do protocolo asyncio.

   Este método tentará estabelecer a conexão em segundo plano. Quando
   tiver sucesso, ele retorna um par "(transport, protocol)".

   A sinopse cronológica da operação subjacente é conforme abaixo:

   1. A conexão é estabelecida e um transporte é criado para ela.

   2. *protocol_factory* é chamada sem argumentos e é esperada que
      retorne uma instância de protocolo.

   3. A instância de protocolo é acoplada com o transporte, através da
      chamada do seu método "connection_made()".

   4. Uma tupla "(transport, protocol)" é retornada ao ter sucesso.

   O transporte criado é um stream bi-direcional dependente de
   implementação.

   Outros argumentos:

   * *ssl*: se fornecido e não for falso, um transporte SSL/TLS é
     criado (por padrão um transporte TCP simples é criado). Se *ssl*
     for um objeto "ssl.SSLContext", este contexto é usado para criar
     o transporte; se *ssl* for "True", um contexto padrão retornado
     de "ssl.create_default_context()" é usado.

     Ver também: Considerações de segurança sobre SSL/TLS

   * *server_hostname* define ou substitui o hostname que o
     certificado do servidor de destino será pareado contra. Deve ser
     passado apenas se *ssl* não for "None". Por padrão o valor do
     argumento *host* é usado. Se *host* for vazio, não existe valor
     padrão e você deve passar um valor para *server_hostname*. Se
     *server_hostname* for uma string vazia, o pareamento de hostname
     é desabilitado (o que é um risco de segurança sério, permitindo
     ataques potenciais man-in-the-middle).

   * *family*, *proto*, *flags* são os endereços familiares,
     protocolos e sinalizadores opcionais a serem passados por
     getaddrinfo() para resolução do *host*. Se fornecidos, eles devem
     ser todos inteiros e constantes correspondentes do módulo
     "socket".

   * *happy_eyeballs_delay*, se fornecido, habilita Happy Eyeballs
     para esta conexão. Ele deve ser um número de ponto flutuante
     representando o tempo em segundos para aguardar uma tentativa de
     conexão encerrar, antes de começar a próxima tentativa em
     paralelo. Este é o "Atraso na tentativa de conexão" conforme
     definido na **RFC 8305**. Um valor padrão sensível recomendado
     pela RFC é "0.25" (250 millisegundos).

   * *interleave* controla o reordenamento de endereços quando um nome
     de servidor resolve para múltiplos endereços IP. Se "0" ou não
     especificado, nenhum reordenamento é feito, e endereços são
     tentados na ordem retornada por "getaddrinfo()". Se um inteiro
     positivo for especificado, os endereços são intercalados por um
     endereço familiar, e o inteiro fornecido é interpretado como
     "Contagem da família do primeiro endereço" conforme definido na
     **RFC 8305**. O padrão é "0" se *happy_eyeballs_delay* não for
     especificado, e "1" se ele for.

   * *sock*, se fornecido, deve ser um objeto "socket.socket" já
     existente, já conectado, para ser usado por transporte. Se *sock*
     é fornecido, *host*, *port*, *family*, *proto*, *flags*,
     *happy_eyeballs_delay*, *interleave* e *local_addr* não devem ser
     especificados.

     Nota:

       The *sock* argument transfers ownership of the socket to the
       transport created. To close the socket, call the transport's
       "close()" method.

   * *local_addr*, se fornecido, é uma tupla de "(local_host,
     local_port)" usada para se ligar ao soquete localmente. O
     *local_host* e a *local_port* são procurados usando
     "getaddrinfo()", de forma similar para *host* e *port*.

   * *ssl_handshake_timeout* é (para uma conexão TLS) o tempo em
     segundos para aguardar pelo encerramento do aperto de mão TLS,
     antes de abortar a conexão. "60.0" segundos se for "None" (valor
     padrão).

   * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL
     shutdown to complete before aborting the connection. "30.0"
     seconds if "None" (default).

   Alterado na versão 3.5: Adicionado suporte para SSL/TLS na
   "ProactorEventLoop".

   Alterado na versão 3.6: The socket option socket.TCP_NODELAY is set
   by default for all TCP connections.

   Alterado na versão 3.7: Adicionado o parâmetro
   *ssl_handshake_timeout*.

   Alterado na versão 3.8: Adicionados os parâmetros
   *happy_eyeballs_delay* e *interleave*.Happy Eyeballs Algorithm:
   Success with Dual-Stack Hosts. When a server's IPv4 path and
   protocol are working, but the server's IPv6 path and protocol are
   not working, a dual-stack client application experiences
   significant connection delay compared to an IPv4-only client.  This
   is undesirable because it causes the dual-stack client to have a
   worse user experience.  This document specifies requirements for
   algorithms that reduce this user-visible delay and provides an
   algorithm.For more information:
   https://datatracker.ietf.org/doc/html/rfc6555

   Alterado na versão 3.11: Added the *ssl_shutdown_timeout*
   parameter.

   Ver também:

     A função "open_connection()" é uma API alternativa de alto nível.
     Ela retorna um par de ("StreamReader", "StreamWriter") que pode
     ser usado diretamente em código async/await.

coroutine 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)

   Cria uma conexão de datagrama.

   The socket family can be either "AF_INET", "AF_INET6", or
   "AF_UNIX", depending on *host* (or the *family* argument, if
   provided).

   The socket type will be "SOCK_DGRAM".

   *protocol_factory* deve ser algo chamável, retornando uma
   implementação de protocolo.

   Uma tupla de "(transport, protocol)" é retornada em caso de
   sucesso.

   Outros argumentos:

   * *local_addr*, se fornecido, é uma tupla de "(local_host,
     local_port)" usada para ligar o soquete localmente. O
     *local_host* e a *local_port* são procurados usando
     "getaddrinfo()".

   * *remote_addr*, se fornecido, é uma tupla de "(remote_host,
     remote_port)" usada para conectar o soquete a um endereço remoto.
     O *remote_host* e a *remote_port* são procurados usando
     "getaddrinfo()".

   * *family*, *proto*, *flags* são os endereços familiares, protocolo
     e flags opcionais a serem passados para "getaddrinfo()" para
     resolução do *host*. Se fornecido, esses devem ser todos inteiros
     do módulo de constantes "socket" correspondente.

   * *reuse_port* tells the kernel to allow this endpoint to be bound
     to the same port as other existing endpoints are bound to, so
     long as they all set this flag when being created. This option is
     not supported on Windows and some Unixes. If the
     socket.SO_REUSEPORT constant is not defined then this capability
     is unsupported.

   * *allow_broadcast* avisa o kernel para permitir que este endpoint
     envie mensagens para o endereço de broadcast.

   * *sock* pode opcionalmente ser especificado em ordem para usar um
     objeto "socket.socket" pre-existente, já conectado, para ser
     usado pelo transporte. Se especificado, *local_addr* e
     *remote_addr* devem ser omitidos (devem ser "None").

     Nota:

       The *sock* argument transfers ownership of the socket to the
       transport created. To close the socket, call the transport's
       "close()" method.

   Veja protocolo UDP eco cliente e protocolo UDP eco servidor para
   exemplos.

   Alterado na versão 3.4.4: The *family*, *proto*, *flags*,
   *reuse_address*, *reuse_port*, *allow_broadcast*, and *sock*
   parameters were added.

   Alterado na versão 3.8: Adicionado suporte para Windows.

   Alterado na versão 3.8.1: The *reuse_address* parameter is no
   longer supported, as using socket.SO_REUSEADDR poses a significant
   security concern for UDP. Explicitly passing "reuse_address=True"
   will raise an exception.Quando múltiplos processos com diferentes
   UIDs atribuem soquetes para um endereço de soquete UDP idêntico com
   "SO_REUSEADDR", pacotes recebidos podem ser distribuídos
   aleatoriamente entre os soquetes.For supported platforms,
   *reuse_port* can be used as a replacement for similar
   functionality. With *reuse_port*, socket.SO_REUSEPORT is used
   instead, which specifically prevents processes with differing UIDs
   from assigning sockets to the same socket address.

   Alterado na versão 3.11: The *reuse_address* parameter, disabled
   since Python 3.8.1, 3.7.6 and 3.6.10, has been entirely removed.

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

   Cria uma conexão Unix.

   The socket family will be "AF_UNIX"; socket type will be
   "SOCK_STREAM".

   Uma tupla de "(transport, protocol)" é retornada em caso de
   sucesso.

   *path* é o nome de um soquete de domínio Unix e é obrigatório, a
   não ser que um parâmetro *sock* seja esecificado. Soquetes Unix
   abstratos, "str", "bytes", e caminhos "Path" são suportados.

   Veja a documentação do método "loop.create_connection()" para
   informações a respeito de argumentos para este método.

   Disponibilidade: Unix.

   Alterado na versão 3.7: Adicionado o parâmetro
   *ssl_handshake_timeout*. O parâmetro *path* agora pode ser um
   *path-like object*.

   Alterado na versão 3.11: Added the *ssl_shutdown_timeout*
   parameter.


Criando servidores de rede
--------------------------

coroutine 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, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True)

   Create a TCP server (socket type "SOCK_STREAM") listening on *port*
   of the *host* address.

   Retorna um objeto "Server".

   Argumentos:

   * *protocol_factory* deve ser algo chamável, retornando uma
     implementação de protocolo.

   * O parâmetro *host* pode ser definido para diversos tipos, o qual
     determina onde o servidor deve escutar:

     * Se *host* for uma string, o servidor TCP está vinculado a
       apenas uma interface de rede, especificada por *host*.

     * Se *host* é uma sequência de strings, o servidor TCP está
       vinculado a todas as interfaces de rede especificadas pela
       sequência.

     * Se *host* é uma string vazia ou "None", todas as interfaces são
       presumidas e uma lista de múltiplos soquetes será retornada
       (muito provavelmente um para IPv4 e outro para IPv6).

   * O parâmetro *port* pode ser definido para especificar qual porta
     o servidor deve escutar. Se "0" ou "None" (o padrão), uma porta
     aleatória disponível será selecionada (note que se *host* resolve
     para múltiplas interfaces de rede, uma porta aleatória diferente
     será selecionada para cada interface).

   * *family* can be set to either "socket.AF_INET" or "AF_INET6" to
     force the socket to use IPv4 or IPv6. If not set, the *family*
     will be determined from host name (defaults to "AF_UNSPEC").

   * *flags* é uma máscara de bits para "getaddrinfo()".

   * *sock* pode opcionalmente ser especificado para usar um objeto
     soquete pré-existente. Se especificado, *host* e *port* não devem
     ser especificados.

     Nota:

       The *sock* argument transfers ownership of the socket to the
       server created. To close the socket, call the server's
       "close()" method.

   * *backlog* é o número máximo de conexões enfileiradas pasadas para
     "listen()" (padrão é 100).

   * *ssl* pode ser definido para uma instância de "SSLContext" para
     habilitar TLS sobre as conexões aceitas.

   * *reuse_address* diz ao kernel para reusar um soquete local em
     estado "TIME_WAIT", serm aguardar pela expiração natural do seu
     tempo limite. Se não especificado, será automaticamente definida
     como "True" no Unix.

   * *reuse_port* diz ao kernel para permitir que este endpoint seja
     vinculado a mesma porta que outros endpoints existentes estão
     vinculados, contanto que todos eles definam este sinalizador
     quando forem criados. Esta opção não é suportada no Windows.

   * *ssl_handshake_timeout* é (para um servidor TLS) o tempo em
     segundos para aguardar pelo aperto de mão TLS ser concluído,
     antes de abortar a conexão. "60.0" segundos se "None" (valor
     padrão).

   * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL
     shutdown to complete before aborting the connection. "30.0"
     seconds if "None" (default).

   * Definir *start_serving* para "True" (o valor padrão) faz o
     servidor criado começar a aceitar conexões imediatamente. Quando
     definido para "False", o usuário deve aguardar com
     "Server.start_serving()" ou "Server.serve_forever()" para fazer o
     servidor começar a aceitar conexões.

   Alterado na versão 3.5: Adicionado suporte para SSL/TLS na
   "ProactorEventLoop".

   Alterado na versão 3.5.1: O parâmetro *host* pode ser uma sequência
   de strings.

   Alterado na versão 3.6: Added *ssl_handshake_timeout* and
   *start_serving* parameters. The socket option socket.TCP_NODELAY is
   set by default for all TCP connections.

   Alterado na versão 3.11: Added the *ssl_shutdown_timeout*
   parameter.

   Ver também:

     A função "start_server()" é uma API alternativa de alto nível que
     retorna um par de "StreamReader" e "StreamWriter" que pode ser
     usado em um código async/await.

coroutine 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)

   Similar to "loop.create_server()" but works with the "AF_UNIX"
   socket family.

   *path* é o nome de um soquete de domínio Unix, e é obrigatório, a
   não ser que um argumento *sock* seja fornecido. Soquetes Unix
   abstratos, "str", "bytes", e caminhos "Path" são suportados.

   Veja a documentação do método "loop.create_server()" para
   informações sobre argumentos para este método.

   Disponibilidade: Unix.

   Alterado na versão 3.7: Adicionados os parâmetros
   *ssl_handshake_timeout* estart_serving*. O parâmetros *path* agora
   pode ser um objeto da classe "Path".

   Alterado na versão 3.11: Added the *ssl_shutdown_timeout*
   parameter.

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

   Envolve uma conexão já aceita em um par transporte/protocolo.

   Este método pode ser usado por servidores que aceitam conexões fora
   do asyncio, mas que usam asyncio para manipulá-las.

   Parâmetros:

   * *protocol_factory* deve ser algo chamável, retornando uma
     implementação de protocolo.

   * *sock* é um objeto soquete pré-existente retornado a partir de
     "socket.accept".

     Nota:

       The *sock* argument transfers ownership of the socket to the
       transport created. To close the socket, call the transport's
       "close()" method.

   * *ssl* pode ser definido para um "SSLContext" para habilitar SSL
     sobre as conexões aceitas.

   * *ssl_handshake_timeout* é (para uma conexão SSL) o tempo em
     segundos para aguardar pelo aperto de mão SSL ser concluído,
     antes de abortar a conexão. "60.0" segundos se "None" (valor
     padrão).

   * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL
     shutdown to complete before aborting the connection. "30.0"
     seconds if "None" (default).

   Retorna um par "(transport, protocol)".

   Novo na versão 3.5.3.

   Alterado na versão 3.7: Adicionado o parâmetro
   *ssl_handshake_timeout*.

   Alterado na versão 3.11: Added the *ssl_shutdown_timeout*
   parameter.


Transferindo arquivos
---------------------

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

   Envia um *file* sobre um *transport*. Retorna o número total de
   bytes enviados.

   O método usa "os.sendfile()" de alto desempenho, se disponível.

   *file* deve ser um objeto arquivo regular aberto em modo binário.

   *offset* indica a partir de onde deve iniciar a leitura do arquivo.
   Se especificado, *count* é o número total de bytes para transmitir,
   ao contrário de transmitir o arquivo até que EOF seja atingido. A
   posição do arquivo é sempre atualizada, mesmo quando este método
   levanta um erro, e "file.tell()" pode ser usado para obter o número
   atual de bytes enviados.

   *fallback* definido para "True" faz o asyncio manualmente ler e
   enviar o arquivo quando a plataforma não suporta a chamada de
   sistema sendfile (por exemplo Windows ou soquete SSL no Unix).

   Levanta "SendfileNotAvailableError" se o sistema não suporta a
   chamada de sistema *sendfile* e *fallback* é "False".

   Novo na versão 3.7.


Atualizando TLS
---------------

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

   Atualiza um conexão baseada em transporte existente para TLS.

   Create a TLS coder/decoder instance and insert it between the
   *transport* and the *protocol*. The coder/decoder implements both
   *transport*-facing protocol and *protocol*-facing transport.

   Return the created two-interface instance. After *await*, the
   *protocol* must stop using the original *transport* and communicate
   with the returned object only because the coder caches
   *protocol*-side data and sporadically exchanges extra TLS session
   packets with *transport*.

   In some situations (e.g. when the passed transport is already
   closing) this may return "None".

   Parâmetros:

   * instâncias de *transport* e *protocol*, que métodos como
     "create_server()" e "create_connection()" retornam.

   * *sslcontext*: uma instância configurada de "SSLContext".

   * *server_side* informe "True" quando uma conexão no lado do
     servidor estiver sendo atualizada (como a que é criada por
     "create_server()").

   * *server_hostname*: define ou substitui o nome do host no qual o
     servidor alvo do certificado será comparado.

   * *ssl_handshake_timeout* é (para uma conexão TLS) o tempo em
     segundos para aguardar pelo encerramento do aperto de mão TLS,
     antes de abortar a conexão. "60.0" segundos se for "None" (valor
     padrão).

   * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL
     shutdown to complete before aborting the connection. "30.0"
     seconds if "None" (default).

   Novo na versão 3.7.

   Alterado na versão 3.11: Added the *ssl_shutdown_timeout*
   parameter.


Observando descritores de arquivo
---------------------------------

loop.add_reader(fd, callback, *args)

   Começa a monitorar o descritor de arquivo *fd* para disponibilidade
   de leitura e invoca a *callback* com os argumentos especificados
   assim que *fd* esteja disponível para leitura.

loop.remove_reader(fd)

   Stop monitoring the *fd* file descriptor for read availability.
   Returns "True" if *fd* was previously being monitored for reads.

loop.add_writer(fd, callback, *args)

   Começa a monitorar o descritor de arquivo *fd* para disponibilidade
   de escrita e invoca a *callback* com os argumentos especificados
   assim que *fd* esteja disponível para escrita.

   Use "functools.partial()" para passar argumentos nomeados para a
   *callback*.

loop.remove_writer(fd)

   Stop monitoring the *fd* file descriptor for write availability.
   Returns "True" if *fd* was previously being monitored for writes.

Veja também a seção de Suporte a Plataformas para algumas limitações
desses métodos.


Trabalhando com objetos soquete diretamente
-------------------------------------------

Em geral, implementações de protocolo que usam APIs baseadas em
transporte, tais como "loop.create_connection()" e
"loop.create_server()" são mais rápidas que implementações que
trabalham com soquetes diretamente. Entretanto, existem alguns casos
de uso quando o desempenho não é crítica, e trabalhar com objetos
"socket" diretamente é mais conveniente.

coroutine loop.sock_recv(sock, nbytes)

   Recebe até *nbytes* do *sock*. Versão assíncrona de
   "socket.recv()".

   Retorna os dados recebidos como um objeto de bytes.

   *sock* deve ser um soquete não bloqueante.

   Alterado na versão 3.7: Apesar deste método sempre ter sido
   documentado como um método de corrotina, versões anteriores ao
   Python 3.7 retornavam um "Future". Desde o Python 3.7 este é um
   método "async def".

coroutine loop.sock_recv_into(sock, buf)

   Dados recebidos do *sock* no buffer *buf*. Modelado baseado no
   método bloqueante "socket.recv_into()".

   Retorna o número de bytes escritos no buffer.

   *sock* deve ser um soquete não bloqueante.

   Novo na versão 3.7.

coroutine loop.sock_recvfrom(sock, bufsize)

   Receive a datagram of up to *bufsize* from *sock*.  Asynchronous
   version of "socket.recvfrom()".

   Return a tuple of (received data, remote address).

   *sock* deve ser um soquete não bloqueante.

   Novo na versão 3.11.

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

   Receive a datagram of up to *nbytes* from *sock* into *buf*.
   Asynchronous version of "socket.recvfrom_into()".

   Return a tuple of (number of bytes received, remote address).

   *sock* deve ser um soquete não bloqueante.

   Novo na versão 3.11.

coroutine loop.sock_sendall(sock, data)

   Envia *data* para o soquete *sock*. Versão assíncrona de
   "socket.sendall()".

   Este método continua a enviar para o soquete até que todos os dados
   em *data* tenham sido enviados ou um erro ocorra. "None" é
   retornado em caso de sucesso. Ao ocorrer um erro, uma exceção é
   levantada. Adicionalmente, não existe nenhuma forma de determinar
   quantos dados, se algum, foram processados com sucesso pelo
   destinatário na conexão.

   *sock* deve ser um soquete não bloqueante.

   Alterado na versão 3.7: Apesar deste método sempre ter sido
   documentado como um método de corrotina, antes do Python 3.7 ele
   retornava um "Future". Desde o Python 3.7, este é um método "async
   def".

coroutine loop.sock_sendto(sock, data, address)

   Send a datagram from *sock* to *address*. Asynchronous version of
   "socket.sendto()".

   Return the number of bytes sent.

   *sock* deve ser um soquete não bloqueante.

   Novo na versão 3.11.

coroutine loop.sock_connect(sock, address)

   Conecta o *sock* em um endereço *address* remoto.

   Versão assíncrona de "socket.connect()".

   *sock* deve ser um soquete não bloqueante.

   Alterado na versão 3.5.2: "address" não precisa mais ser resolvido.
   "sock_connect" irá tentar verificar se *address* já está resolvido
   chamando "socket.inet_pton()". Se não estiver, "loop.getaddrinfo()"
   será usado para resolver *address*.

   Ver também:

     "loop.create_connection()" e  "asyncio.open_connection()".

coroutine loop.sock_accept(sock)

   Aceita uma conexão. Modelado baseado no método bloqueante
   "socket.accept()".

   O soquete deve estar vinculado a um endereço e escutando por
   conexões. O valor de retorno é um par "(conn, address)" onde *conn*
   é um *novo* objeto de soquete usável para enviar e receber dados na
   conexão, e *address* é o endereço vinculado ao soquete no outro
   extremo da conexão.

   *sock* deve ser um soquete não bloqueante.

   Alterado na versão 3.7: Apesar deste método sempre ter sido
   documentado como um método de corrotina, antes do Python 3.7 ele
   retornava um "Future". Desde o Python 3.7, este é um método "async
   def".

   Ver também: "loop.create_server()" e "start_server()".

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

   Envia um arquivo usando "os.sendfile" de alto desempenho se
   possível. Retorna o número total de bytes enviados.

   Versão assíncrona de "socket.sendfile()".

   *sock* deve ser um "socket" "socket.SOCK_STREAM" não bloqueante.

   *file* deve ser um objeto arquivo regular aberto em modo binário.

   *offset* indica a partir de onde deve iniciar a leitura do arquivo.
   Se especificado, *count* é o número total de bytes para transmitir,
   ao contrário de transmitir o arquivo até que EOF seja atingido. A
   posição do arquivo é sempre atualizada, mesmo quando este método
   levanta um erro, e "file.tell()" pode ser usado para obter o número
   atual de bytes enviados.

   *fallback*, quando definido para "True", faz asyncio ler e enviar
   manualmente o arquivo, quando a plataforma não suporta a chamada de
   sistema sendfile (por exemplo Windows ou soquete SSL no Unix).

   Levanta "SendfileNotAvailableError" se o sistema não suporta
   chamadas de sistema *sendfile* e *fallback* é "False".

   *sock* deve ser um soquete não bloqueante.

   Novo na versão 3.7.


DNS
---

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

   Versão assíncrona de "socket.getaddrinfo()".

coroutine loop.getnameinfo(sockaddr, flags=0)

   Versão assíncrona de "socket.getnameinfo()".

Alterado na versão 3.7: Ambos os métodos *getaddrinfo* e *getnameinfo*
sempre foram documentados para retornar uma corrotina, mas antes do
Python 3.7 eles estavam, na verdade, retornando objetos
"asyncio.Future". A partir do Python 3.7, ambos os métodos são
corrotinas.


Trabalhando com encadeamentos
-----------------------------

coroutine loop.connect_read_pipe(protocol_factory, pipe)

   Registra o extremo da leitura de um *pipe* no laço de eventos.

   *protocol_factory* deve ser um chamável que retorne uma
   implementação do protocolo asyncio.

   *pipe* é um *objeto arquivo ou similar*.

   Retorna um par "(transport, protocol)", onde *transport* suporta a
   interface "ReadTransport" e *protocol* é um objeto instanciado pelo
   *protocol_factory*.

   Com o "SelectorEventLoop" do laço de eventos, o *pipe* é definido
   para modo não bloqueante.

coroutine loop.connect_write_pipe(protocol_factory, pipe)

   Registra o extremo de escrita do *pipe* no laço de eventos.

   *protocol_factory* deve ser um chamável que retorne uma
   implementação do protocolo asyncio.

   *pipe* é um *objeto arquivo ou similar*.

   Retorna um part "(transport, protocol)", onde *transport* suporta a
   interface "WriteTransport" e *protocol* é um objeto instanciado
   pelo *protocol_factory*.

   Com o "SelectorEventLoop" do laço de eventos, o *pipe* é definido
   para modo não bloqueante.

Nota:

  "SelectorEventLoop" não suporta os métodos acima no Windows. Use
  "ProactorEventLoop" ao invés para Windows.

Ver também:

  Os métodos "loop.subprocess_exec()" e "loop.subprocess_shell()".


Sinais Unix
-----------

loop.add_signal_handler(signum, callback, *args)

   Define *callback* como o tratador para o sinal *signum*.

   A função de retorno será invocada pelo *loop*, juntamente com
   outras funções de retorno enfileiradas e corrotinas executáveis
   daquele laço de eventos. Ao contrário de tratadores de sinal
   registrados usando "signal.signal()", uma função de retorno
   registrada com esta função tem autorização para interagir com o
   laço de eventos.

   Levanta "ValueError" se o número do sinal é inválido ou impossível
   de capturar. Levanta "RuntimeError" se existe um problema definindo
   o tratador.

   Use "functools.partial()" para passar argumentos nomeados para a
   *callback*.

   Assim como "signal.signal()", esta função deve ser invocada na
   thread principal.

loop.remove_signal_handler(sig)

   Remove o tratador para o sinal *sig*.

   Retorna "True" se o tratador de sinal foi removido, ou "False" se
   nenhum tratador foi definido para o sinal fornecido.

   Disponibilidade: Unix.

Ver também: O módulo "signal".


Executando código em conjuntos de threads ou processos
------------------------------------------------------

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

   Providencia para a *func* ser chamada no executor especificado.

   O argumento *executor* deve ser uma instância
   "concurrent.futures.Executor". O executor padrão é usado se
   *executor* for "None".

   Exemplo:

      import asyncio
      import concurrent.futures

      def blocking_io():
          # File operations (such as logging) can block the
          # event loop: run them in a thread pool.
          with open('/dev/urandom', 'rb') as f:
              return f.read(100)

      def cpu_bound():
          # CPU-bound operations will block the event loop:
          # in general it is preferable to run them in a
          # process pool.
          return sum(i * i for i in range(10 ** 7))

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

          ## Options:

          # 1. Run in the default loop's executor:
          result = await loop.run_in_executor(
              None, blocking_io)
          print('default thread pool', result)

          # 2. Run in a custom thread pool:
          with concurrent.futures.ThreadPoolExecutor() as pool:
              result = await loop.run_in_executor(
                  pool, blocking_io)
              print('custom thread pool', result)

          # 3. Run in a custom process pool:
          with concurrent.futures.ProcessPoolExecutor() as pool:
              result = await loop.run_in_executor(
                  pool, cpu_bound)
              print('custom process pool', result)

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

   Note that the entry point guard ("if __name__ == '__main__'") is
   required for option 3 due to the peculiarities of
   "multiprocessing", which is used by "ProcessPoolExecutor". See Safe
   importing of main module.

   Este método retorna um objeto "asyncio.Future".

   Use "functools.partial()" para passar argumentos nomeados para
   *func*.

   Alterado na versão 3.5.3: "loop.run_in_executor()" não configura
   mais o atributo "max_workers" do executor do conjunto de thread que
   ele cria, ao invés disso ele deixa para o executor do conjunto de
   thread ("ThreadPoolExecutor") para setar o valor padrão.

loop.set_default_executor(executor)

   Set *executor* as the default executor used by "run_in_executor()".
   *executor* must be an instance of "ThreadPoolExecutor".

   Alterado na versão 3.11: *executor* must be an instance of
   "ThreadPoolExecutor".


Tratando erros da API
---------------------

Permite customizar como exceções são tratadas no laço de eventos.

loop.set_exception_handler(handler)

   Define *handler* como o novo tratador de exceções do laço de
   eventos.

   Se *handler* for "None", o tratador de exceções padrão será
   definido. Caso contrário, *handler* deve ser um chamável com a
   assinatura combinando "(loop, context)", onde "loop" é a referência
   para o laço de eventos ativo, e "context" é um objeto "dict"
   contendo os detalhes da exceção (veja a documentação
   "call_exception_handler()" para detalhes a respeito do contexto).

loop.get_exception_handler()

   Retorna o tratador de exceção atual, ou "None" se nenhum tratador
   de exceção customizado foi definido.

   Novo na versão 3.5.2.

loop.default_exception_handler(context)

   Tratador de exceção padrão.

   Isso é chamado quando uma exceção ocorre e nenhum tratador de
   exceção foi definido. Isso pode ser chamado por um tratador de
   exceção customizado que quer passar adiante para o comportamento do
   tratador padrão.

   parâmetro *context* tem o mesmo significado que em
   "call_exception_handler()".

loop.call_exception_handler(context)

   Chama o tratador de exceção do laço de eventos atual.

   *context* é um objeto "dict" contendo as seguintes chaves (novas
   chaves podem ser introduzidas em versões futuras do Python):

   * 'message': Mensagem de erro;

   * 'exception' (opcional): Objeto Exception;

   * 'future' (opcional): instância de "asyncio.Future";

   * 'task' (opcional): instância de "asyncio.Task";

   * 'handle' (opcional): instância de "asyncio.Handle";

   * 'protocol' (opcional): instância de Protocol;

   * 'transport' (opcional): instância de Transport;

   * 'socket' (opcional): instância de "socket.socket";

   * 'asyncgen' (opcional): Gerador assíncrono que causou
        a exceção.

   Nota:

     Este método não deve ser substituído em subclasses de laços de
     evento. Para tratamento de exceções customizadas, use o método
     "set_exception_handler()".


Habilitando o modo de debug
---------------------------

loop.get_debug()

   Obtém o modo de debug ("bool") do laço de eventos.

   O valor padrão é "True" se a variável de ambiente
   "PYTHONASYNCIODEBUG" estiver definida para uma string não vazia,
   "False" caso contrário.

loop.set_debug(enabled: bool)

   Define o modo de debug do laço de eventos.

   Alterado na versão 3.7: O novo Modo de Desenvolvimento do Python
   agora também pode ser usado para habilitar o modo de debug.

loop.slow_callback_duration

   This attribute can be used to set the minimum execution duration in
   seconds that is considered "slow". When debug mode is enabled,
   "slow" callbacks are logged.

   Default value is 100 milliseconds.

Ver também: O modo de debug de asyncio.


Executando Subprocessos
-----------------------

Métodos descritos nestas sub-seções são de baixo nível. Em código
async/await regular, considere usar as funções convenientes de alto
nível "asyncio.create_subprocess_shell()" e
"asyncio.create_subprocess_exec()" ao invés.

Nota:

  No Windows, o laço de eventos padrão "ProactorEventLoop" oferece
  suporte pra subprocessos, enquanto "SelectorEventLoop", não. Veja
  Suporte para subprocessos no Windows para detalhes.

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

   Cria um subprocesso a partir de um ou mais argumentos de string
   especificados por *args*.

   *args* deve ser uma lista de strings representada por:

   * "str";

   * ou "bytes", encodados na codificação do sistema de arquivos.

   A primeira string especifica o programa executável, e as strings
   remanescentes especificam os argumentos. Juntas, argumentos em
   string formam o "argv" do programa.

   Isto é similar a classe "subprocess.Popen" da biblioteca padrão ser
   chamada com "shell=False" e a lista de strings ser passada como o
   primeiro argumento; entretanto, onde "Popen" recebe apenas um
   argumento no qual é uma lista de strings, *subprocess_exec* recebe
   múltiplos argumentos string.

   O *protocol_factory* deve ser um chamável que retorne uma subclasse
   da classe "asyncio.SubprocessProtocol".

   Outros parâmetros:

   * *stdin* pode ser qualquer um destes:

     * um objeto arquivo ou similar representando um encadeamento para
       ser conectado ao stream de entrada padrão do subprocesso usando
       "connect_write_pipe()"

     * a constante "subprocess.PIPE" (padrão), a qual criará um novo
       encadeamento e conectar a ele,

     * o valor "None", o qual fará o subprocesso herdar o descritor de
       arquivo deste processo

     * a constante "subprocess.DEVNULL", a qual indica que o arquivo
       especial "os.devnull" será usado

   * *stdout* pode ser qualquer um destes:

     * um objeto arquivo ou similar representando um encadeamento para
       ser conectado ao stream de saída padrão do subprocesso usando
       "connect_write_pipe()"

     * a constante "subprocess.PIPE" (padrão), a qual criará um novo
       encadeamento e conectar a ele,

     * o valor "None", o qual fará o subprocesso herdar o descritor de
       arquivo deste processo

     * a constante "subprocess.DEVNULL", a qual indica que o arquivo
       especial "os.devnull" será usado

   * *stderr* pode ser qualquer um destes:

     * um objeto arquivo ou similar representando um encadeamento para
       ser conectado ao stream de erro padrão do subprocesso usando
       "connect_write_pipe()"

     * a constante "subprocess.PIPE" (padrão), a qual criará um novo
       encadeamento e conectar a ele,

     * o valor "None", o qual fará o subprocesso herdar o descritor de
       arquivo deste processo

     * a constante "subprocess.DEVNULL", a qual indica que o arquivo
       especial "os.devnull" será usado

     * a constante "subprocess.STDOUT", a qual irá conectar o stream
       de erro padrão ao stream de saída padrão do processo

   * Todos os outros argumentos nomeados são passados para
     "subprocess.Popen" sem interpretação, exceto *bufsize*,
     *universal_newlines*, *shell*, *text*, *encoding* e *errors*, os
     quais não devem ser especificados de forma alguma.

     A API de subprocesso "asyncio" não suporta decodificar os streams
     como texto. "bytes.decode()" pode ser usado para converter os
     bytes retornados do stream para texto.

   Veja o construtor da classe "subprocess.Popen" para documentação
   sobre outros argumentos.

   Retorna um par "(transport, protocol)", onde *transport* conforma
   com a classe base "asyncio.SubprocessTransport" e *protocol* é um
   objeto instanciado pelo *protocol_factory*.

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

   Cria um subprocesso a partir do *cmd*, o qual pode ser um "str" ou
   uma string de "bytes" codificada na codificação do sistema de
   arquivos, usando a sintaxe "shell" da plataforma.

   Isto é similar a classe "subprocess.Popen" da biblioteca padrão
   sendo chanada com "shell=True".

   O argumento *protocol_factory* deve ser um chamável que retorna uma
   subclasse da classe "SubprocessProtocol".

   Veja "subprocess_exec()" para mais detalhes sobre os argumentos
   remanescentes.

   Retorna um par "(transport, protocol)", onde *transport* conforma
   com a classe base "SubprocessTransport" e *protocol* é um objeto
   instanciado pelo *protocol_factory*.

Nota:

  É responsabilidade da aplicação garantir que todos os espaços em
  branco e caracteres especiais sejam tratados apropriadamente para
  evitar vulnerabilidades de injeção shell . A função "shlex.quote()"
  pode ser usada para escapar espaços em branco e caracteres especiais
  apropriadamente em strings que serão usadas para construir comandos
  shell.


Tratadores de função de retorno
===============================

class asyncio.Handle

   Um objeto invólucro de função de retorno retornado por
   "loop.call_soon()", "loop.call_soon_threadsafe()".

   cancel()

      Cancela a função de retorno. Se a função de retorno já tiver
      sido cancelada ou executada, este método não tem efeito.

   cancelled()

      Retorna "True" se a função de retorno foi cancelada.

      Novo na versão 3.7.

class asyncio.TimerHandle

   Um objeto invólucro de função de retorno retornado por
   "loop.call_later()", e "loop.call_at()".

   Esta classe é uma subclasse de "Handle".

   when()

      Retorna o tempo de uma função de retorno agendada como "float"
      segundos.

      O tempo é um timestamp absoluto, usando a mesma referência de
      tempo que "loop.time()".

      Novo na versão 3.7.


Objetos Server
==============

Objetos Server são criados pelas funções "loop.create_server()",
"loop.create_unix_server()", "start_server()", e
"start_unix_server()".

Do not instantiate the "Server" class directly.

class asyncio.Server

   Objetos *Server* são gerenciadores de contexto assíncronos. Quando
   usados em uma instrução "async with", é garantido que o objeto
   Server está fechado e não está aceitando novas conexões quando a
   instrução "async with" estiver completa:

      srv = await loop.create_server(...)

      async with srv:
          # some code

      # At this point, srv is closed and no longer accepts new connections.

   Alterado na versão 3.7: Objeto Server é um gerenciador de contexto
   assíncrono desde o Python 3.7.

   Alterado na versão 3.11: This class was exposed publicly as
   "asyncio.Server" in Python 3.9.11, 3.10.3 and 3.11.

   close()

      Para de servir: fecha soquetes que estavam ouvindo e define o
      atributo "sockets" para "None".

      Os soquetes que representam conexões de clientes existentes que
      estão chegando são deixados em aberto.

      O servidor é fechado de forma assíncrona, use a corrotina
      "wait_closed()" para aguartar até que o servidor esteja fechado.

   get_loop()

      Retorna o laço de eventos associado com o objeto server.

      Novo na versão 3.7.

   coroutine start_serving()

      Começa a aceitar conexões.

      This method is idempotent, so it can be called when the server
      is already serving.

      O parâmetro somente-nomeado *start_serving* para
      "loop.create_server()" e "asyncio.start_server()" permite criar
      um objeto Server que não está aceitando conexões inicialmente.
      Neste caso "Server.start_serving()", ou "Server.serve_forever()"
      podem ser usados para fazer o Server começar a aceitar conexões.

      Novo na versão 3.7.

   coroutine serve_forever()

      Começa a aceitar conexões até que a corrotina seja cancelada.
      Cancelamento da task "serve_forever" causa o fechamento do
      servidor.

      Este método pode ser chamado se o servidor já estiver aceitando
      conexões. Apenas uma task "serve_forever" pode existir para cada
      objeto *Server*.

      Exemplo:

         async def client_connected(reader, writer):
             # Communicate with the client with
             # reader/writer streams.  For example:
             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))

      Novo na versão 3.7.

   is_serving()

      Retorna "True" se o servidor estiver aceitando novas conexões.

      Novo na versão 3.7.

   coroutine wait_closed()

      Aguarda até o método "close()" completar.

   sockets

      List of socket-like objects, "asyncio.trsock.TransportSocket",
      which the server is listening on.

      Alterado na versão 3.7: Antes do Python 3.7 "Server.sockets" era
      usado para retornar uma lista interna de soquetes do server
      diretamente. No uma cópia dessa lista é retornada.


Implementações do Laço de Eventos
=================================

asyncio vem com duas implementações de laço de eventos diferente:
"SelectorEventLoop" e "ProactorEventLoop".

Por padrão asyncio está configurado para usar "SelectorEventLoop" no
Unix e "ProactorEventLoop" no Windows.

class asyncio.SelectorEventLoop

   Um laço de eventos baseado no módulo "selectors".

   Usa o *seletor* mais eficiente disponível para a plataforma
   fornecida. Também é possível configurar manualmente a implementação
   exata do seletor a ser utilizada:

      import asyncio
      import selectors

      class MyPolicy(asyncio.DefaultEventLoopPolicy):
         def new_event_loop(self):
            selector = selectors.SelectSelector()
            return asyncio.SelectorEventLoop(selector)

      asyncio.set_event_loop_policy(MyPolicy())

   Disponibilidade: Unix, Windows.

class asyncio.ProactorEventLoop

   Um laço de eventos para Windows que usa "Conclusão de Portas I/O"
   (IOCP).

   Disponibilidade: Windows.

   Ver também: Documentação da MSDN sobre conclusão de portas I/O.

class asyncio.AbstractEventLoop

   Classe base abstrata para laços de eventos compatíveis com asyncio.

   The Métodos do laço de eventos section lists all methods that an
   alternative implementation of "AbstractEventLoop" should have
   defined.


Exemplos
========

Perceba que todos os exemplos nesta seção **propositalmente** mostram
como usar as APIs de baixo nível do laço de eventos, tais como
"loop.run_forever()" e "loop.call_soon()". Aplicações asyncio modernas
raramente precisam ser escritas desta forma; considere usar as funções
de alto nível como "asyncio.run()".


Hello World com call_soon()
---------------------------

Um exemplo usando o método "loop.call_soon()" para agendar uma função
de retorno. A função de retorno exibe ""Hello World"" e então para o
laço de eventos:

   import asyncio

   def hello_world(loop):
       """A callback to print 'Hello World' and stop the event loop"""
       print('Hello World')
       loop.stop()

   loop = asyncio.new_event_loop()

   # Schedule a call to hello_world()
   loop.call_soon(hello_world, loop)

   # Blocking call interrupted by loop.stop()
   try:
       loop.run_forever()
   finally:
       loop.close()

Ver também:

  Um exemplo similar a Hello World criado com uma corrotina e a função
  "run()".


Exibe a data atual com call_later()
-----------------------------------

Um exemplo de uma função de retorno mostrando a data atual a cada
segundo. A função de retorno usa o método "loop.call_later()" para
reagendar a si mesma depois de 5 segundos, e então para o laço de
eventos:

   import asyncio
   import datetime

   def display_date(end_time, loop):
       print(datetime.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()

   # Schedule the first call to display_date()
   end_time = loop.time() + 5.0
   loop.call_soon(display_date, end_time, loop)

   # Blocking call interrupted by loop.stop()
   try:
       loop.run_forever()
   finally:
       loop.close()

Ver também:

  Um exemplo similar a data atual criado com uma corrotina e a função
  "run()".


Observa um descritor de arquivo por eventos de leitura
------------------------------------------------------

Aguarda até que um descritor de arquivo tenha recebido alguns dados
usando o método "loop.add_reader()" e então fecha o laço de eventos:

   import asyncio
   from socket import socketpair

   # Create a pair of connected file descriptors
   rsock, wsock = socketpair()

   loop = asyncio.new_event_loop()

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

       # We are done: unregister the file descriptor
       loop.remove_reader(rsock)

       # Stop the event loop
       loop.stop()

   # Register the file descriptor for read event
   loop.add_reader(rsock, reader)

   # Simulate the reception of data from the network
   loop.call_soon(wsock.send, 'abc'.encode())

   try:
       # Run the event loop
       loop.run_forever()
   finally:
       # We are done. Close sockets and the event loop.
       rsock.close()
       wsock.close()
       loop.close()

Ver também:

  * Um exemplo similar usando transportes, protocolos, e o método
    "loop.create_connection()".

  * Outro exemplo similar usando a função de alto nível
    "asyncio.open_connection()" e streams.


Define tratadores de sinais para SIGINT e SIGTERM
-------------------------------------------------

(Este exemplo de "signals" apenas funciona no Unix.)

Register handlers for signals "SIGINT" and "SIGTERM" using the
"loop.add_signal_handler()" method:

   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())
