Event Loop

Preface

The event loop is the core of every asyncio application.Event loops run asynchronous tasks and callbacks, perform networkIO operations, and run subprocesses.

Application developers should typically use the high-level asyncio functions,such asasyncio.run(), and should rarely need to reference the loopobject or call its methods. This section is intended mostly for authorsof lower-level code, libraries, and frameworks, who need finer control overthe event loop behavior.

Obtaining the Event Loop

The following low-level functions can be used to get, set, or createan event loop:

asyncio.get_running_loop()

Return the running event loop in the current OS thread.

If there is no running event loop aRuntimeError is raised.This function can only be called from a coroutine or a callback.

New in version 3.7.

asyncio.get_event_loop()

Get the current event loop.

If there is no current event loop set in the current OS thread,the OS thread is main, andset_event_loop() has not yetbeen called, asyncio will create a new event loop and set it as thecurrent one.

Because this function has rather complex behavior (especiallywhen custom event loop policies are in use), using theget_running_loop() function is preferred toget_event_loop()in coroutines and callbacks.

Consider also using theasyncio.run() function instead of usinglower level functions to manually create and close an event loop.

asyncio.set_event_loop(loop)

Setloop as a current event loop for the current OS thread.

asyncio.new_event_loop()

Create a new event loop object.

Note that the behaviour ofget_event_loop(),set_event_loop(),andnew_event_loop() functions can be altered bysetting a custom event loop policy.

Contents

This documentation page contains the following sections:

Event Loop Methods

Event loops havelow-level APIs for the following:

Running and stopping the loop

loop.run_until_complete(future)

Run until thefuture (an instance ofFuture) hascompleted.

If the argument is acoroutine object itis implicitly scheduled to run as aasyncio.Task.

Return the Future’s result or raise its exception.

loop.run_forever()

Run the event loop untilstop() is called.

Ifstop() is called beforerun_forever() is called,the loop will poll the I/O selector once with a timeout of zero,run all callbacks scheduled in response to I/O events (andthose that were already scheduled), and then exit.

Ifstop() is called whilerun_forever() is running,the loop will run the current batch of callbacks and then exit.Note that new callbacks scheduled by callbacks will not run in thiscase; instead, they will run the next timerun_forever() orrun_until_complete() is called.

loop.stop()

Stop the event loop.

loop.is_running()

ReturnTrue if the event loop is currently running.

loop.is_closed()

ReturnTrue if the event loop was closed.

loop.close()

Close the event loop.

The loop must not be running when this function is called.Any pending callbacks will be discarded.

This method clears all queues and shuts down the executor, but doesnot wait for the executor to finish.

This method is idempotent and irreversible. No other methodsshould be called after the event loop is closed.

coroutineloop.shutdown_asyncgens()

Schedule all currently openasynchronous generator objects toclose with anaclose() call. After calling this method,the event loop will issue a warning if a new asynchronous generatoris iterated. This should be used to reliably finalize all scheduledasynchronous generators.

Note that there is no need to call this function whenasyncio.run() is used.

Example:

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

New in version 3.6.

Scheduling callbacks

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

Schedule acallback to be called withargs arguments atthe next iteration of the event loop.

Callbacks are called in the order in which they are registered.Each callback will be called exactly once.

An optional keyword-onlycontext argument allows specifying acustomcontextvars.Context for thecallback to run in.The current context is used when nocontext is provided.

An instance ofasyncio.Handle is returned, which can beused later to cancel the callback.

This method is not thread-safe.

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

A thread-safe variant ofcall_soon(). Must be used toschedule callbacksfrom another thread.

See theconcurrency and multithreadingsection of the documentation.

Changed in version 3.7:Thecontext keyword-only parameter was added. SeePEP 567for more details.

Note

Mostasyncio scheduling functions don’t allow passingkeyword arguments. To do that, usefunctools.partial():

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

Using partial objects is usually more convenient than using lambdas,as asyncio can render partial objects better in debug and errormessages.

Scheduling delayed callbacks

Event loop provides mechanisms to schedule callback functionsto be called at some point in the future. Event loop uses monotonicclocks to track time.

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

Schedulecallback to be called after the givendelaynumber of seconds (can be either an int or a float).

An instance ofasyncio.TimerHandle is returned which canbe used to cancel the callback.

callback will be called exactly once. If two callbacks arescheduled for exactly the same time, the order in which theyare called is undefined.

The optional positionalargs will be passed to the callback whenit is called. If you want the callback to be called with keywordarguments usefunctools.partial().

An optional keyword-onlycontext argument allows specifying acustomcontextvars.Context for thecallback to run in.The current context is used when nocontext is provided.

Changed in version 3.7:Thecontext keyword-only parameter was added. SeePEP 567for more details.

Changed in version 3.7.1:In Python 3.7.0 and earlier with the default event loop implementation,thedelay could not exceed one day.This has been fixed in Python 3.7.1.

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

Schedulecallback to be called at the given absolute timestampwhen (an int or a float), using the same time reference asloop.time().

This method’s behavior is the same ascall_later().

An instance ofasyncio.TimerHandle is returned which canbe used to cancel the callback.

Changed in version 3.7:Thecontext keyword-only parameter was added. SeePEP 567for more details.

Changed in version 3.7.1:In Python 3.7.0 and earlier with the default event loop implementation,the difference betweenwhen and the current time could not exceedone day. This has been fixed in Python 3.7.1.

loop.time()

Return the current time, as afloat value, according tothe event loop’s internal monotonic clock.

Note

Changed in version 3.8:In Python 3.7 and earlier timeouts (relativedelay or absolutewhen)should not exceed one day. This has been fixed in Python 3.8.

See also

Theasyncio.sleep() function.

Creating Futures and Tasks

loop.create_future()

Create anasyncio.Future object attached to the event loop.

This is the preferred way to create Futures in asyncio. This letsthird-party event loops provide alternative implementations ofthe Future object (with better performance or instrumentation).

New in version 3.5.2.

loop.create_task(coro)

Schedule the execution of aCoroutines.Return aTask object.

Third-party event loops can use their own subclass ofTaskfor interoperability. In this case, the result type is a subclassofTask.

loop.set_task_factory(factory)

Set a task factory that will be used byloop.create_task().

Iffactory isNone the default task factory will be set.Otherwise,factory must be acallable with the signature matching(loop,coro), whereloop is a reference to the activeevent loop, andcoro is a coroutine object. The callablemust return aasyncio.Future-compatible object.

loop.get_task_factory()

Return a task factory orNone if the default one is in use.

Opening network connections

coroutineloop.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)

Open a streaming transport connection to a givenaddress specified byhost andport.

The socket family can be eitherAF_INET orAF_INET6 depending onhost (or thefamilyargument, if provided).

The socket type will beSOCK_STREAM.

protocol_factory must be a callable returning anasyncio protocol implementation.

This method will try to establish the connection in the background.When successful, it returns a(transport,protocol) pair.

The chronological synopsis of the underlying operation is as follows:

  1. The connection is established and atransportis created for it.

  2. protocol_factory is called without arguments and is expected toreturn aprotocol instance.

  3. The protocol instance is coupled with the transport by calling itsconnection_made() method.

  4. A(transport,protocol) tuple is returned on success.

The created transport is an implementation-dependent bidirectionalstream.

Other arguments:

  • ssl: if given and not false, a SSL/TLS transport is created(by default a plain TCP transport is created). Ifssl isassl.SSLContext object, this context is used to createthe transport; ifssl isTrue, a default context returnedfromssl.create_default_context() is used.

  • server_hostname sets or overrides the hostname that the targetserver’s certificate will be matched against. Should only be passedifssl is notNone. By default the value of thehost argumentis used. Ifhost is empty, there is no default and you must pass avalue forserver_hostname. Ifserver_hostname is an emptystring, hostname matching is disabled (which is a serious securityrisk, allowing for potential man-in-the-middle attacks).

  • family,proto,flags are the optional address family, protocoland flags to be passed through to getaddrinfo() forhost resolution.If given, these should all be integers from the correspondingsocket module constants.

  • sock, if given, should be an existing, already connectedsocket.socket object to be used by the transport.Ifsock is given, none ofhost,port,family,proto,flagsandlocal_addr should be specified.

  • local_addr, if given, is a(local_host,local_port) tuple usedto bind the socket to locally. Thelocal_host andlocal_portare looked up usinggetaddrinfo(), similarly tohost andport.

  • ssl_handshake_timeout is (for a TLS connection) the time in secondsto wait for the TLS handshake to complete before aborting the connection.60.0 seconds ifNone (default).

New in version 3.7:Thessl_handshake_timeout parameter.

Changed in version 3.6:The socket optionTCP_NODELAY is set by defaultfor all TCP connections.

Changed in version 3.5:Added support for SSL/TLS inProactorEventLoop.

See also

Theopen_connection() function is a high-level alternativeAPI. It returns a pair of (StreamReader,StreamWriter)that can be used directly in async/await code.

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

Note

The parameterreuse_address is no longer supported, as usingSO_REUSEADDR poses a significant security concern forUDP. Explicitly passingreuse_address=True will raise an exception.

When multiple processes with differing UIDs assign sockets to anindentical UDP socket address withSO_REUSEADDR, incoming packets canbecome randomly distributed among the sockets.

For supported platforms,reuse_port can be used as a replacement forsimilar functionality. Withreuse_port,SO_REUSEPORT is used instead, which specificallyprevents processes with differing UIDs from assigning sockets to the samesocket address.

Create a datagram connection.

The socket family can be eitherAF_INET,AF_INET6, orAF_UNIX,depending onhost (or thefamily argument, if provided).

The socket type will beSOCK_DGRAM.

protocol_factory must be a callable returning aprotocol implementation.

A tuple of(transport,protocol) is returned on success.

Other arguments:

  • local_addr, if given, is a(local_host,local_port) tuple usedto bind the socket to locally. Thelocal_host andlocal_portare looked up usinggetaddrinfo().

  • remote_addr, if given, is a(remote_host,remote_port) tuple usedto connect the socket to a remote address. Theremote_host andremote_port are looked up usinggetaddrinfo().

  • family,proto,flags are the optional address family, protocoland flags to be passed through togetaddrinfo() forhostresolution. If given, these should all be integers from thecorrespondingsocket module constants.

  • reuse_port tells the kernel to allow this endpoint to be bound to thesame port as other existing endpoints are bound to, so long as they allset this flag when being created. This option is not supported on Windowsand some Unixes. If theSO_REUSEPORT constant is notdefined then this capability is unsupported.

  • allow_broadcast tells the kernel to allow this endpoint to sendmessages to the broadcast address.

  • sock can optionally be specified in order to use a preexisting,already connected,socket.socket object to be used by thetransport. If specified,local_addr andremote_addr should be omitted(must beNone).

On Windows, withProactorEventLoop, this method is not supported.

SeeUDP echo client protocol andUDP echo server protocol examples.

Changed in version 3.4.4:Thefamily,proto,flags,reuse_address,reuse_port,*allow_broadcast, andsock parameters were added.

Changed in version 3.7.6:Thereuse_address parameter is no longer supported due to securityconcerns.

coroutineloop.create_unix_connection(protocol_factory,path=None,*,ssl=None,sock=None,server_hostname=None,ssl_handshake_timeout=None)

Create a Unix connection.

The socket family will beAF_UNIX; sockettype will beSOCK_STREAM.

A tuple of(transport,protocol) is returned on success.

path is the name of a Unix domain socket and is required,unless asock parameter is specified. Abstract Unix sockets,str,bytes, andPath paths aresupported.

See the documentation of theloop.create_connection() methodfor information about arguments to this method.

Availability: Unix.

New in version 3.7:Thessl_handshake_timeout parameter.

Changed in version 3.7:Thepath parameter can now be apath-like object.

Creating network servers

coroutineloop.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,start_serving=True)

Create a TCP server (socket typeSOCK_STREAM) listeningonport of thehost address.

Returns aServer object.

Arguments:

  • protocol_factory must be a callable returning aprotocol implementation.

  • Thehost parameter can be set to several types which determine wherethe server would be listening:

    • Ifhost is a string, the TCP server is bound to a single networkinterface specified byhost.

    • Ifhost is a sequence of strings, the TCP server is bound to allnetwork interfaces specified by the sequence.

    • Ifhost is an empty string orNone, all interfaces areassumed and a list of multiple sockets will be returned (most likelyone for IPv4 and another one for IPv6).

  • family can be set to eithersocket.AF_INET orAF_INET6 to force the socket to use IPv4 or IPv6.If not set, thefamily will be determined from host name(defaults toAF_UNSPEC).

  • flags is a bitmask forgetaddrinfo().

  • sock can optionally be specified in order to use a preexistingsocket object. If specified,host andport must not be specified.

  • backlog is the maximum number of queued connections passed tolisten() (defaults to 100).

  • ssl can be set to anSSLContext instance to enableTLS over the accepted connections.

  • reuse_address tells the kernel to reuse a local socket inTIME_WAIT state, without waiting for its natural timeout toexpire. If not specified will automatically be set toTrue onUnix.

  • reuse_port tells the kernel to allow this endpoint to be bound to thesame port as other existing endpoints are bound to, so long as they allset this flag when being created. This option is not supported onWindows.

  • ssl_handshake_timeout is (for a TLS server) the time in seconds to waitfor the TLS handshake to complete before aborting the connection.60.0 seconds ifNone (default).

  • start_serving set toTrue (the default) causes the created serverto start accepting connections immediately. When set toFalse,the user should await onServer.start_serving() orServer.serve_forever() to make the server to start acceptingconnections.

New in version 3.7:Addedssl_handshake_timeout andstart_serving parameters.

Changed in version 3.6:The socket optionTCP_NODELAY is set by defaultfor all TCP connections.

Changed in version 3.5:Added support for SSL/TLS inProactorEventLoop.

Changed in version 3.5.1:Thehost parameter can be a sequence of strings.

See also

Thestart_server() function is a higher-level alternative APIthat returns a pair ofStreamReader andStreamWriterthat can be used in an async/await code.

coroutineloop.create_unix_server(protocol_factory,path=None,*,sock=None,backlog=100,ssl=None,ssl_handshake_timeout=None,start_serving=True)

Similar toloop.create_server() but works with theAF_UNIX socket family.

path is the name of a Unix domain socket, and is required,unless asock argument is provided. Abstract Unix sockets,str,bytes, andPath pathsare supported.

See the documentation of theloop.create_server() methodfor information about arguments to this method.

Availability: Unix.

New in version 3.7:Thessl_handshake_timeout andstart_serving parameters.

Changed in version 3.7:Thepath parameter can now be aPath object.

coroutineloop.connect_accepted_socket(protocol_factory,sock,*,ssl=None,ssl_handshake_timeout=None)

Wrap an already accepted connection into a transport/protocol pair.

This method can be used by servers that accept connections outsideof asyncio but that use asyncio to handle them.

Parameters:

  • protocol_factory must be a callable returning aprotocol implementation.

  • sock is a preexisting socket object returned fromsocket.accept.

  • ssl can be set to anSSLContext to enable SSL overthe accepted connections.

  • ssl_handshake_timeout is (for an SSL connection) the time in seconds towait for the SSL handshake to complete before aborting the connection.60.0 seconds ifNone (default).

Returns a(transport,protocol) pair.

New in version 3.7:Thessl_handshake_timeout parameter.

New in version 3.5.3.

Transferring files

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

Send afile over atransport. Return the total number of bytessent.

The method uses high-performanceos.sendfile() if available.

file must be a regular file object opened in binary mode.

offset tells from where to start reading the file. If specified,count is the total number of bytes to transmit as opposed tosending the file until EOF is reached. File position is always updated,even when this method raises an error, andfile.tell() can be used to obtain the actualnumber of bytes sent.

fallback set toTrue makes asyncio to manually read and sendthe file when the platform does not support the sendfile system call(e.g. Windows or SSL socket on Unix).

RaiseSendfileNotAvailableError if the system does not supportthesendfile syscall andfallback isFalse.

New in version 3.7.

TLS Upgrade

coroutineloop.start_tls(transport,protocol,sslcontext,*,server_side=False,server_hostname=None,ssl_handshake_timeout=None)

Upgrade an existing transport-based connection to TLS.

Return a new transport instance, that theprotocol must start usingimmediately after theawait. Thetransport instance passed tothestart_tls method should never be used again.

Parameters:

  • transport andprotocol instances that methods likecreate_server() andcreate_connection() return.

  • sslcontext: a configured instance ofSSLContext.

  • server_side passTrue when a server-side connection is beingupgraded (like the one created bycreate_server()).

  • server_hostname: sets or overrides the host name that the targetserver’s certificate will be matched against.

  • ssl_handshake_timeout is (for a TLS connection) the time in seconds towait for the TLS handshake to complete before aborting the connection.60.0 seconds ifNone (default).

New in version 3.7.

Watching file descriptors

loop.add_reader(fd,callback,*args)

Start monitoring thefd file descriptor for read availability andinvokecallback with the specified arguments oncefd is available forreading.

loop.remove_reader(fd)

Stop monitoring thefd file descriptor for read availability.

loop.add_writer(fd,callback,*args)

Start monitoring thefd file descriptor for write availability andinvokecallback with the specified arguments oncefd is available forwriting.

Usefunctools.partial()to pass keyword arguments tocallback.

loop.remove_writer(fd)

Stop monitoring thefd file descriptor for write availability.

See alsoPlatform Support sectionfor some limitations of these methods.

Working with socket objects directly

In general, protocol implementations that use transport-based APIssuch asloop.create_connection() andloop.create_server()are faster than implementations that work with sockets directly.However, there are some use cases when performance is not critical, andworking withsocket objects directly is moreconvenient.

coroutineloop.sock_recv(sock,nbytes)

Receive up tonbytes fromsock. Asynchronous version ofsocket.recv().

Return the received data as a bytes object.

sock must be a non-blocking socket.

Changed in version 3.7:Even though this method was always documented as a coroutinemethod, releases before Python 3.7 returned aFuture.Since Python 3.7 this is anasyncdef method.

coroutineloop.sock_recv_into(sock,buf)

Receive data fromsock into thebuf buffer. Modeled after the blockingsocket.recv_into() method.

Return the number of bytes written to the buffer.

sock must be a non-blocking socket.

New in version 3.7.

coroutineloop.sock_sendall(sock,data)

Senddata to thesock socket. Asynchronous version ofsocket.sendall().

This method continues to send to the socket until either all dataindata has been sent or an error occurs.None is returnedon success. On error, an exception is raised. Additionally, there is no wayto determine how much data, if any, was successfully processed by thereceiving end of the connection.

sock must be a non-blocking socket.

Changed in version 3.7:Even though the method was always documented as a coroutinemethod, before Python 3.7 it returned anFuture.Since Python 3.7, this is anasyncdef method.

coroutineloop.sock_connect(sock,address)

Connectsock to a remote socket ataddress.

Asynchronous version ofsocket.connect().

sock must be a non-blocking socket.

Changed in version 3.5.2:address no longer needs to be resolved.sock_connectwill try to check if theaddress is already resolved by callingsocket.inet_pton(). If not,loop.getaddrinfo() will be used to resolve theaddress.

coroutineloop.sock_accept(sock)

Accept a connection. Modeled after the blockingsocket.accept() method.

The socket must be bound to an address and listeningfor connections. The return value is a pair(conn,address) whereconnis anew socket object usable to send and receive data on the connection,andaddress is the address bound to the socket on the other end of theconnection.

sock must be a non-blocking socket.

Changed in version 3.7:Even though the method was always documented as a coroutinemethod, before Python 3.7 it returned aFuture.Since Python 3.7, this is anasyncdef method.

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

Send a file using high-performanceos.sendfile if possible.Return the total number of bytes sent.

Asynchronous version ofsocket.sendfile().

sock must be a non-blockingsocket.SOCK_STREAMsocket.

file must be a regular file object open in binary mode.

offset tells from where to start reading the file. If specified,count is the total number of bytes to transmit as opposed tosending the file until EOF is reached. File position is always updated,even when this method raises an error, andfile.tell() can be used to obtain the actualnumber of bytes sent.

fallback, when set toTrue, makes asyncio manually read and sendthe file when the platform does not support the sendfile syscall(e.g. Windows or SSL socket on Unix).

RaiseSendfileNotAvailableError if the system does not supportsendfile syscall andfallback isFalse.

sock must be a non-blocking socket.

New in version 3.7.

DNS

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

Asynchronous version ofsocket.getaddrinfo().

coroutineloop.getnameinfo(sockaddr,flags=0)

Asynchronous version ofsocket.getnameinfo().

Changed in version 3.7:Bothgetaddrinfo andgetnameinfo methods were always documentedto return a coroutine, but prior to Python 3.7 they were, in fact,returningasyncio.Future objects. Starting with Python 3.7both methods are coroutines.

Working with pipes

coroutineloop.connect_read_pipe(protocol_factory,pipe)

Register the read end ofpipe in the event loop.

protocol_factory must be a callable returning anasyncio protocol implementation.

pipe is afile-like object.

Return pair(transport,protocol), wheretransport supportstheReadTransport interface andprotocol is an objectinstantiated by theprotocol_factory.

WithSelectorEventLoop event loop, thepipe is set tonon-blocking mode.

coroutineloop.connect_write_pipe(protocol_factory,pipe)

Register the write end ofpipe in the event loop.

protocol_factory must be a callable returning anasyncio protocol implementation.

pipe isfile-like object.

Return pair(transport,protocol), wheretransport supportsWriteTransport interface andprotocol is an objectinstantiated by theprotocol_factory.

WithSelectorEventLoop event loop, thepipe is set tonon-blocking mode.

Note

SelectorEventLoop does not support the above methods onWindows. UseProactorEventLoop instead for Windows.

Unix signals

loop.add_signal_handler(signum,callback,*args)

Setcallback as the handler for thesignum signal.

The callback will be invoked byloop, along with other queued callbacksand runnable coroutines of that event loop. Unlike signal handlersregistered usingsignal.signal(), a callback registered with thisfunction is allowed to interact with the event loop.

RaiseValueError if the signal number is invalid or uncatchable.RaiseRuntimeError if there is a problem setting up the handler.

Usefunctools.partial()to pass keyword arguments tocallback.

Likesignal.signal(), this function must be invoked in the mainthread.

loop.remove_signal_handler(sig)

Remove the handler for thesig signal.

ReturnTrue if the signal handler was removed, orFalse ifno handler was set for the given signal.

Availability: Unix.

See also

Thesignal module.

Executing code in thread or process pools

awaitableloop.run_in_executor(executor,func,*args)

Arrange forfunc to be called in the specified executor.

Theexecutor argument should be anconcurrent.futures.Executorinstance. The default executor is used ifexecutor isNone.

Example:

importasyncioimportconcurrent.futuresdefblocking_io():# File operations (such as logging) can block the# event loop: run them in a thread pool.withopen('/dev/urandom','rb')asf:returnf.read(100)defcpu_bound():# CPU-bound operations will block the event loop:# in general it is preferable to run them in a# process pool.returnsum(i*iforiinrange(10**7))asyncdefmain():loop=asyncio.get_running_loop()## Options:# 1. Run in the default loop's executor:result=awaitloop.run_in_executor(None,blocking_io)print('default thread pool',result)# 2. Run in a custom thread pool:withconcurrent.futures.ThreadPoolExecutor()aspool:result=awaitloop.run_in_executor(pool,blocking_io)print('custom thread pool',result)# 3. Run in a custom process pool:withconcurrent.futures.ProcessPoolExecutor()aspool:result=awaitloop.run_in_executor(pool,cpu_bound)print('custom process pool',result)asyncio.run(main())

This method returns aasyncio.Future object.

Usefunctools.partial()to pass keyword arguments tofunc.

Changed in version 3.5.3:loop.run_in_executor() no longer configures themax_workers of the thread pool executor it creates, insteadleaving it up to the thread pool executor(ThreadPoolExecutor) to set thedefault.

loop.set_default_executor(executor)

Setexecutor as the default executor used byrun_in_executor().executor should be an instance ofThreadPoolExecutor.

Deprecated since version 3.7:Using an executor that is not an instance ofThreadPoolExecutor is deprecated andwill trigger an error in Python 3.9.

executor must be an instance ofconcurrent.futures.ThreadPoolExecutor.

Error Handling API

Allows customizing how exceptions are handled in the event loop.

loop.set_exception_handler(handler)

Sethandler as the new event loop exception handler.

Ifhandler isNone, the default exception handler willbe set. Otherwise,handler must be a callable with the signaturematching(loop,context), whereloopis a reference to the active event loop, andcontextis adict object containing the details of the exception(seecall_exception_handler() documentation for detailsabout context).

loop.get_exception_handler()

Return the current exception handler, orNone if no customexception handler was set.

New in version 3.5.2.

loop.default_exception_handler(context)

Default exception handler.

This is called when an exception occurs and no exceptionhandler is set. This can be called by a custom exceptionhandler that wants to defer to the default handler behavior.

context parameter has the same meaning as incall_exception_handler().

loop.call_exception_handler(context)

Call the current event loop exception handler.

context is adict object containing the following keys(new keys may be introduced in future Python versions):

  • ‘message’: Error message;

  • ‘exception’ (optional): Exception object;

  • ‘future’ (optional):asyncio.Future instance;

  • ‘handle’ (optional):asyncio.Handle instance;

  • ‘protocol’ (optional):Protocol instance;

  • ‘transport’ (optional):Transport instance;

  • ‘socket’ (optional):socket.socket instance.

Note

This method should not be overloaded in subclassedevent loops. For custom exception handling, usetheset_exception_handler() method.

Enabling debug mode

loop.get_debug()

Get the debug mode (bool) of the event loop.

The default value isTrue if the environment variablePYTHONASYNCIODEBUG is set to a non-empty string,Falseotherwise.

loop.set_debug(enabled: bool)

Set the debug mode of the event loop.

Changed in version 3.7:The new-Xdev command line option can now also be usedto enable the debug mode.

Running Subprocesses

Methods described in this subsections are low-level. In regularasync/await code consider using the high-levelasyncio.create_subprocess_shell() andasyncio.create_subprocess_exec() convenience functions instead.

Note

The default asyncio event loop onWindows does not supportsubprocesses. SeeSubprocess Support on Windows for details.

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

Create a subprocess from one or more string arguments specified byargs.

args must be a list of strings represented by:

The first string specifies the program executable,and the remaining strings specify the arguments. Together, stringarguments form theargv of the program.

This is similar to the standard librarysubprocess.Popenclass called withshell=False and the list of strings passed asthe first argument; however, wherePopen takesa single argument which is list of strings,subprocess_exectakes multiple string arguments.

Theprotocol_factory must be a callable returning a subclass of theasyncio.SubprocessProtocol class.

Other parameters:

  • stdin: either a file-like object representing a pipe to beconnected to the subprocess’s standard input stream usingconnect_write_pipe(), or thesubprocess.PIPE constant (default). By default a newpipe will be created and connected.

  • stdout: either a file-like object representing the pipe to beconnected to the subprocess’s standard output stream usingconnect_read_pipe(), or thesubprocess.PIPE constant (default). By default a new pipewill be created and connected.

  • stderr: either a file-like object representing the pipe to beconnected to the subprocess’s standard error stream usingconnect_read_pipe(), or one ofsubprocess.PIPE (default) orsubprocess.STDOUTconstants.

    By default a new pipe will be created and connected. Whensubprocess.STDOUT is specified, the subprocess’ standarderror stream will be connected to the same pipe as the standardoutput stream.

  • All other keyword arguments are passed tosubprocess.Popenwithout interpretation, except forbufsize,universal_newlinesandshell, which should not be specified at all.

See the constructor of thesubprocess.Popen classfor documentation on other arguments.

Returns a pair of(transport,protocol), wheretransportconforms to theasyncio.SubprocessTransport base class andprotocol is an object instantiated by theprotocol_factory.

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

Create a subprocess fromcmd, which can be astr or abytes string encoded to thefilesystem encoding,using the platform’s “shell” syntax.

This is similar to the standard librarysubprocess.Popenclass called withshell=True.

Theprotocol_factory must be a callable returning a subclass of theSubprocessProtocol class.

Seesubprocess_exec() for more details aboutthe remaining arguments.

Returns a pair of(transport,protocol), wheretransportconforms to theSubprocessTransport base class andprotocol is an object instantiated by theprotocol_factory.

Note

It is the application’s responsibility to ensure that all whitespaceand special characters are quoted appropriately to avoidshell injectionvulnerabilities. Theshlex.quote() function can be used toproperly escape whitespace and special characters in strings thatare going to be used to construct shell commands.

Callback Handles

classasyncio.Handle

A callback wrapper object returned byloop.call_soon(),loop.call_soon_threadsafe().

cancel()

Cancel the callback. If the callback has already been canceledor executed, this method has no effect.

cancelled()

ReturnTrue if the callback was cancelled.

New in version 3.7.

classasyncio.TimerHandle

A callback wrapper object returned byloop.call_later(),andloop.call_at().

This class is a subclass ofHandle.

when()

Return a scheduled callback time asfloat seconds.

The time is an absolute timestamp, using the same timereference asloop.time().

New in version 3.7.

Server Objects

Server objects are created byloop.create_server(),loop.create_unix_server(),start_server(),andstart_unix_server() functions.

Do not instantiate the class directly.

classasyncio.Server

Server objects are asynchronous context managers. When used in anasyncwith statement, it’s guaranteed that the Server object isclosed and not accepting new connections when theasyncwithstatement is completed:

srv=awaitloop.create_server(...)asyncwithsrv:# some code# At this point, srv is closed and no longer accepts new connections.

Changed in version 3.7:Server object is an asynchronous context manager since Python 3.7.

close()

Stop serving: close listening sockets and set thesocketsattribute toNone.

The sockets that represent existing incoming client connectionsare left open.

The server is closed asynchronously, use thewait_closed()coroutine to wait until the server is closed.

get_loop()

Return the event loop associated with the server object.

New in version 3.7.

coroutinestart_serving()

Start accepting connections.

This method is idempotent, so it can be called whenthe server is already being serving.

Thestart_serving keyword-only parameter toloop.create_server() andasyncio.start_server() allows creating a Server objectthat is not accepting connections initially. In this caseServer.start_serving(), orServer.serve_forever() can be usedto make the Server start accepting connections.

New in version 3.7.

coroutineserve_forever()

Start accepting connections until the coroutine is cancelled.Cancellation ofserve_forever task causes the serverto be closed.

This method can be called if the server is already acceptingconnections. Only oneserve_forever task can exist peroneServer object.

Example:

asyncdefclient_connected(reader,writer):# Communicate with the client with# reader/writer streams.  For example:awaitreader.readline()asyncdefmain(host,port):srv=awaitasyncio.start_server(client_connected,host,port)awaitsrv.serve_forever()asyncio.run(main('127.0.0.1',0))

New in version 3.7.

is_serving()

ReturnTrue if the server is accepting new connections.

New in version 3.7.

coroutinewait_closed()

Wait until theclose() method completes.

sockets

List ofsocket.socket objects the server is listening on,orNone if the server is closed.

Changed in version 3.7:Prior to Python 3.7Server.sockets used to return aninternal list of server sockets directly. In 3.7 a copyof that list is returned.

Event Loop Implementations

asyncio ships with two different event loop implementations:SelectorEventLoop andProactorEventLoop.

By default asyncio is configured to useSelectorEventLoopon all platforms.

classasyncio.SelectorEventLoop

An event loop based on theselectors module.

Uses the most efficientselector available for the givenplatform. It is also possible to manually configure theexact selector implementation to be used:

importasyncioimportselectorsselector=selectors.SelectSelector()loop=asyncio.SelectorEventLoop(selector)asyncio.set_event_loop(loop)

Availability: Unix, Windows.

classasyncio.ProactorEventLoop

An event loop for Windows that uses “I/O Completion Ports” (IOCP).

Availability: Windows.

An example how to useProactorEventLoop on Windows:

importasyncioimportsysifsys.platform=='win32':loop=asyncio.ProactorEventLoop()asyncio.set_event_loop(loop)
classasyncio.AbstractEventLoop

Abstract base class for asyncio-compliant event loops.

TheEvent Loop Methods section lists allmethods that an alternative implementation ofAbstractEventLoopshould have defined.

Examples

Note that all examples in this sectionpurposefully show howto use the low-level event loop APIs, such asloop.run_forever()andloop.call_soon(). Modern asyncio applications rarelyneed to be written this way; consider using the high-level functionslikeasyncio.run().

Hello World with call_soon()

An example using theloop.call_soon() method to schedule acallback. The callback displays"HelloWorld" and then stops theevent loop:

importasynciodefhello_world(loop):"""A callback to print 'Hello World' and stop the event loop"""print('Hello World')loop.stop()loop=asyncio.get_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()

See also

A similarHello Worldexample created with a coroutine and therun() function.

Display the current date with call_later()

An example of a callback displaying the current date every second. Thecallback uses theloop.call_later() method to reschedule itselfafter 5 seconds, and then stops the event loop:

importasyncioimportdatetimedefdisplay_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.get_event_loop()# Schedule the first call to display_date()end_time=loop.time()+5.0loop.call_soon(display_date,end_time,loop)# Blocking call interrupted by loop.stop()try:loop.run_forever()finally:loop.close()

See also

A similarcurrent date examplecreated with a coroutine and therun() function.

Watch a file descriptor for read events

Wait until a file descriptor received some data using theloop.add_reader() method and then close the event loop:

importasynciofromsocketimportsocketpair# Create a pair of connected file descriptorsrsock,wsock=socketpair()loop=asyncio.get_event_loop()defreader():data=rsock.recv(100)print("Received:",data.decode())# We are done: unregister the file descriptorloop.remove_reader(rsock)# Stop the event looploop.stop()# Register the file descriptor for read eventloop.add_reader(rsock,reader)# Simulate the reception of data from the networkloop.call_soon(wsock.send,'abc'.encode())try:# Run the event looploop.run_forever()finally:# We are done. Close sockets and the event loop.rsock.close()wsock.close()loop.close()

See also

Set signal handlers for SIGINT and SIGTERM

(Thissignals example only works on Unix.)

Register handlers for signalsSIGINT andSIGTERMusing theloop.add_signal_handler() method:

importasyncioimportfunctoolsimportosimportsignaldefask_exit(signame,loop):print("got signal%s: exit"%signame)loop.stop()asyncdefmain():loop=asyncio.get_running_loop()forsignamein{'SIGINT','SIGTERM'}:loop.add_signal_handler(getattr(signal,signame),functools.partial(ask_exit,signame,loop))awaitasyncio.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())