Coroutines and Tasks

This section outlines high-level asyncio APIs to work with coroutinesand Tasks.

Coroutines

Source code:Lib/asyncio/coroutines.py


Coroutines declared with the async/await syntax is thepreferred way of writing asyncio applications. For example, the followingsnippet of code prints “hello”, waits 1 second,and then prints “world”:

>>>importasyncio>>>asyncdefmain():...print('hello')...awaitasyncio.sleep(1)...print('world')>>>asyncio.run(main())helloworld

Note that simply calling a coroutine will not schedule it tobe executed:

>>>main()<coroutine object main at 0x1053bb7c8>

To actually run a coroutine, asyncio provides the following mechanisms:

  • Theasyncio.run() function to run the top-levelentry point “main()” function (see the above example.)

  • Awaiting on a coroutine. The following snippet of code willprint “hello” after waiting for 1 second, and then print “world”after waiting foranother 2 seconds:

    importasyncioimporttimeasyncdefsay_after(delay,what):awaitasyncio.sleep(delay)print(what)asyncdefmain():print(f"started at{time.strftime('%X')}")awaitsay_after(1,'hello')awaitsay_after(2,'world')print(f"finished at{time.strftime('%X')}")asyncio.run(main())

    Expected output:

    startedat17:13:52helloworldfinishedat17:13:55
  • Theasyncio.create_task() function to run coroutinesconcurrently as asyncioTasks.

    Let’s modify the above example and run twosay_after coroutinesconcurrently:

    asyncdefmain():task1=asyncio.create_task(say_after(1,'hello'))task2=asyncio.create_task(say_after(2,'world'))print(f"started at{time.strftime('%X')}")# Wait until both tasks are completed (should take# around 2 seconds.)awaittask1awaittask2print(f"finished at{time.strftime('%X')}")

    Note that expected output now shows that the snippet runs1 second faster than before:

    startedat17:14:32helloworldfinishedat17:14:34
  • Theasyncio.TaskGroup class provides a more modernalternative tocreate_task().Using this API, the last example becomes:

    asyncdefmain():asyncwithasyncio.TaskGroup()astg:task1=tg.create_task(say_after(1,'hello'))task2=tg.create_task(say_after(2,'world'))print(f"started at{time.strftime('%X')}")# The await is implicit when the context manager exits.print(f"finished at{time.strftime('%X')}")

    The timing and output should be the same as for the previous version.

    Added in version 3.11:asyncio.TaskGroup.

Awaitables

We say that an object is anawaitable object if it can be usedin anawait expression. Many asyncio APIs are designed toaccept awaitables.

There are three main types ofawaitable objects:coroutines,Tasks, andFutures.

Coroutines

Python coroutines areawaitables and therefore can be awaited fromother coroutines:

importasyncioasyncdefnested():return42asyncdefmain():# Nothing happens if we just call "nested()".# A coroutine object is created but not awaited,# so it *won't run at all*.nested()# will raise a "RuntimeWarning".# Let's do it differently now and await it:print(awaitnested())# will print "42".asyncio.run(main())

Important

In this documentation the term “coroutine” can be used fortwo closely related concepts:

  • acoroutine function: anasyncdef function;

  • acoroutine object: an object returned by calling acoroutine function.

Tasks

Tasks are used to schedule coroutinesconcurrently.

When a coroutine is wrapped into aTask with functions likeasyncio.create_task() the coroutine is automaticallyscheduled to run soon:

importasyncioasyncdefnested():return42asyncdefmain():# Schedule nested() to run soon concurrently# with "main()".task=asyncio.create_task(nested())# "task" can now be used to cancel "nested()", or# can simply be awaited to wait until it is complete:awaittaskasyncio.run(main())

Futures

AFuture is a speciallow-level awaitable object thatrepresents aneventual result of an asynchronous operation.

When a Future object isawaited it means that the coroutine willwait until the Future is resolved in some other place.

Future objects in asyncio are needed to allow callback-based codeto be used with async/await.

Normallythere is no need to create Future objects at theapplication level code.

Future objects, sometimes exposed by libraries and some asyncioAPIs, can be awaited:

asyncdefmain():awaitfunction_that_returns_a_future_object()# this is also valid:awaitasyncio.gather(function_that_returns_a_future_object(),some_python_coroutine())

A good example of a low-level function that returns a Future objectisloop.run_in_executor().

Creating Tasks

Source code:Lib/asyncio/tasks.py


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

Wrap thecorocoroutine into aTaskand schedule its execution. Return the Task object.

Ifname is notNone, it is set as the name of the task usingTask.set_name().

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

The task is executed in the loop returned byget_running_loop(),RuntimeError is raised if there is no running loop incurrent thread.

Note

asyncio.TaskGroup.create_task() is a new alternativeleveraging structural concurrency; it allows for waitingfor a group of related tasks with strong safety guarantees.

Important

Save a reference to the result of this function, to avoida task disappearing mid-execution. The event loop only keepsweak references to tasks. A task that isn’t referenced elsewheremay get garbage collected at any time, even before it’s done.For reliable “fire-and-forget” background tasks, gather them ina collection:

background_tasks=set()foriinrange(10):task=asyncio.create_task(some_coro(param=i))# Add task to the set. This creates a strong reference.background_tasks.add(task)# To prevent keeping references to finished tasks forever,# make each task remove its own reference from the set after# completion:task.add_done_callback(background_tasks.discard)

Added in version 3.7.

Changed in version 3.8:Added thename parameter.

Changed in version 3.11:Added thecontext parameter.

Task Cancellation

Tasks can easily and safely be cancelled.When a task is cancelled,asyncio.CancelledError will be raisedin the task at the next opportunity.

It is recommended that coroutines usetry/finally blocks to robustlyperform clean-up logic. In caseasyncio.CancelledErroris explicitly caught, it should generally be propagated whenclean-up is complete.asyncio.CancelledError directly subclassesBaseException so most code will not need to be aware of it.

The asyncio components that enable structured concurrency, likeasyncio.TaskGroup andasyncio.timeout(),are implemented using cancellation internally and might misbehave ifa coroutine swallowsasyncio.CancelledError. Similarly, user codeshould not generally calluncancel.However, in cases when suppressingasyncio.CancelledError istruly desired, it is necessary to also calluncancel() to completelyremove the cancellation state.

Task Groups

Task groups combine a task creation API with a convenientand reliable way to wait for all tasks in the group to finish.

classasyncio.TaskGroup

Anasynchronous context managerholding a group of tasks.Tasks can be added to the group usingcreate_task().All tasks are awaited when the context manager exits.

Added in version 3.11.

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

Create a task in this task group.The signature matches that ofasyncio.create_task().If the task group is inactive (e.g. not yet entered,already finished, or in the process of shutting down),we will close the givencoro.

Changed in version 3.13:Close the given coroutine if the task group is not active.

Example:

asyncdefmain():asyncwithasyncio.TaskGroup()astg:task1=tg.create_task(some_coro(...))task2=tg.create_task(another_coro(...))print(f"Both tasks have completed now:{task1.result()},{task2.result()}")

Theasyncwith statement will wait for all tasks in the group to finish.While waiting, new tasks may still be added to the group(for example, by passingtg into one of the coroutinesand callingtg.create_task() in that coroutine).Once the last task has finished and theasyncwith block is exited,no new tasks may be added to the group.

The first time any of the tasks belonging to the group failswith an exception other thanasyncio.CancelledError,the remaining tasks in the group are cancelled.No further tasks can then be added to the group.At this point, if the body of theasyncwith statement is still active(i.e.,__aexit__() hasn’t been called yet),the task directly containing theasyncwith statement is also cancelled.The resultingasyncio.CancelledError will interrupt anawait,but it will not bubble out of the containingasyncwith statement.

Once all tasks have finished, if any tasks have failedwith an exception other thanasyncio.CancelledError,those exceptions are combined in anExceptionGroup orBaseExceptionGroup(as appropriate; see their documentation)which is then raised.

Two base exceptions are treated specially:If any task fails withKeyboardInterrupt orSystemExit,the task group still cancels the remaining tasks and waits for them,but then the initialKeyboardInterrupt orSystemExitis re-raised instead ofExceptionGroup orBaseExceptionGroup.

If the body of theasyncwith statement exits with an exception(so__aexit__() is called with an exception set),this is treated the same as if one of the tasks failed:the remaining tasks are cancelled and then waited for,and non-cancellation exceptions are grouped into anexception group and raised.The exception passed into__aexit__(),unless it isasyncio.CancelledError,is also included in the exception group.The same special case is made forKeyboardInterrupt andSystemExit as in the previous paragraph.

Task groups are careful not to mix up the internal cancellation used to“wake up” their__aexit__() with cancellation requestsfor the task in which they are running made by other parties.In particular, when one task group is syntactically nested in another,and both experience an exception in one of their child tasks simultaneously,the inner task group will process its exceptions, and then the outer task groupwill receive another cancellation and process its own exceptions.

In the case where a task group is cancelled externally and also mustraise anExceptionGroup, it will call the parent task’scancel() method. This ensures that aasyncio.CancelledError will be raised at the nextawait, so the cancellation is not lost.

Task groups preserve the cancellation countreported byasyncio.Task.cancelling().

Changed in version 3.13:Improved handling of simultaneous internal and external cancellationsand correct preservation of cancellation counts.

Terminating a Task Group

While terminating a task group is not natively supported by the standardlibrary, termination can be achieved by adding an exception-raising taskto the task group and ignoring the raised exception:

importasynciofromasyncioimportTaskGroupclassTerminateTaskGroup(Exception):"""Exception raised to terminate a task group."""asyncdefforce_terminate_task_group():"""Used to force termination of a task group."""raiseTerminateTaskGroup()asyncdefjob(task_id,sleep_time):print(f'Task{task_id}: start')awaitasyncio.sleep(sleep_time)print(f'Task{task_id}: done')asyncdefmain():try:asyncwithTaskGroup()asgroup:# spawn some tasksgroup.create_task(job(1,0.5))group.create_task(job(2,1.5))# sleep for 1 secondawaitasyncio.sleep(1)# add an exception-raising task to force the group to terminategroup.create_task(force_terminate_task_group())except*TerminateTaskGroup:passasyncio.run(main())

Expected output:

Task 1: startTask 2: startTask 1: done

Sleeping

asyncasyncio.sleep(delay,result=None)

Block fordelay seconds.

Ifresult is provided, it is returned to the callerwhen the coroutine completes.

sleep() always suspends the current task, allowing other tasksto run.

Setting the delay to 0 provides an optimized path to allow othertasks to run. This can be used by long-running functions to avoidblocking the event loop for the full duration of the function call.

Example of coroutine displaying the current date every secondfor 5 seconds:

importasyncioimportdatetimeasyncdefdisplay_date():loop=asyncio.get_running_loop()end_time=loop.time()+5.0whileTrue:print(datetime.datetime.now())if(loop.time()+1.0)>=end_time:breakawaitasyncio.sleep(1)asyncio.run(display_date())

Changed in version 3.10:Removed theloop parameter.

Changed in version 3.13:RaisesValueError ifdelay isnan.

Running Tasks Concurrently

awaitableasyncio.gather(*aws,return_exceptions=False)

Runawaitable objects in theawssequenceconcurrently.

If any awaitable inaws is a coroutine, it is automaticallyscheduled as a Task.

If all awaitables are completed successfully, the result is anaggregate list of returned values. The order of result valuescorresponds to the order of awaitables inaws.

Ifreturn_exceptions isFalse (default), the firstraised exception is immediately propagated to the task thatawaits ongather(). Other awaitables in theaws sequencewon’t be cancelled and will continue to run.

Ifreturn_exceptions isTrue, exceptions are treated thesame as successful results, and aggregated in the result list.

Ifgather() iscancelled, all submitted awaitables(that have not completed yet) are alsocancelled.

If any Task or Future from theaws sequence iscancelled, it istreated as if it raisedCancelledError – thegather()call isnot cancelled in this case. This is to prevent thecancellation of one submitted Task/Future to cause otherTasks/Futures to be cancelled.

Note

A new alternative to create and run tasks concurrently andwait for their completion isasyncio.TaskGroup.TaskGroupprovides stronger safety guarantees thangather for scheduling a nesting of subtasks:if a task (or a subtask, a task scheduled by a task)raises an exception,TaskGroup will, whilegather will not,cancel the remaining scheduled tasks).

Example:

importasyncioasyncdeffactorial(name,number):f=1foriinrange(2,number+1):print(f"Task{name}: Compute factorial({number}), currently i={i}...")awaitasyncio.sleep(1)f*=iprint(f"Task{name}: factorial({number}) ={f}")returnfasyncdefmain():# Schedule three calls *concurrently*:L=awaitasyncio.gather(factorial("A",2),factorial("B",3),factorial("C",4),)print(L)asyncio.run(main())# Expected output:##     Task A: Compute factorial(2), currently i=2...#     Task B: Compute factorial(3), currently i=2...#     Task C: Compute factorial(4), currently i=2...#     Task A: factorial(2) = 2#     Task B: Compute factorial(3), currently i=3...#     Task C: Compute factorial(4), currently i=3...#     Task B: factorial(3) = 6#     Task C: Compute factorial(4), currently i=4...#     Task C: factorial(4) = 24#     [2, 6, 24]

Note

Ifreturn_exceptions is false, cancelling gather() after ithas been marked done won’t cancel any submitted awaitables.For instance, gather can be marked done after propagating anexception to the caller, therefore, callinggather.cancel()after catching an exception (raised by one of the awaitables) fromgather won’t cancel any other awaitables.

Changed in version 3.7:If thegather itself is cancelled, the cancellation ispropagated regardless ofreturn_exceptions.

Changed in version 3.10:Removed theloop parameter.

Deprecated since version 3.10:Deprecation warning is emitted if no positional arguments are providedor not all positional arguments are Future-like objectsand there is no running event loop.

Eager Task Factory

asyncio.eager_task_factory(loop,coro,*,name=None,context=None)

A task factory for eager task execution.

When using this factory (vialoop.set_task_factory(asyncio.eager_task_factory)),coroutines begin execution synchronously duringTask construction.Tasks are only scheduled on the event loop if they block.This can be a performance improvement as the overhead of loop schedulingis avoided for coroutines that complete synchronously.

A common example where this is beneficial is coroutines which employcaching or memoization to avoid actual I/O when possible.

Note

Immediate execution of the coroutine is a semantic change.If the coroutine returns or raises, the task is never scheduledto the event loop. If the coroutine execution blocks, the task isscheduled to the event loop. This change may introduce behaviorchanges to existing applications. For example,the application’s task execution order is likely to change.

Added in version 3.12.

asyncio.create_eager_task_factory(custom_task_constructor)

Create an eager task factory, similar toeager_task_factory(),using the providedcustom_task_constructor when creating a new task insteadof the defaultTask.

custom_task_constructor must be acallable with the signature matchingthe signature ofTask.__init__.The callable must return aasyncio.Task-compatible object.

This function returns acallable intended to be used as a task factory of anevent loop vialoop.set_task_factory(factory)).

Added in version 3.12.

Shielding From Cancellation

awaitableasyncio.shield(aw)

Protect anawaitable objectfrom beingcancelled.

Ifaw is a coroutine it is automatically scheduled as a Task.

The statement:

task=asyncio.create_task(something())res=awaitshield(task)

is equivalent to:

res=awaitsomething()

except that if the coroutine containing it is cancelled, theTask running insomething() is not cancelled. From the pointof view ofsomething(), the cancellation did not happen.Although its caller is still cancelled, so the “await” expressionstill raises aCancelledError.

Ifsomething() is cancelled by other means (i.e. from withinitself) that would also cancelshield().

If it is desired to completely ignore cancellation (not recommended)theshield() function should be combined with a try/exceptclause, as follows:

task=asyncio.create_task(something())try:res=awaitshield(task)exceptCancelledError:res=None

Important

Save a reference to tasks passed to this function, to avoida task disappearing mid-execution. The event loop only keepsweak references to tasks. A task that isn’t referenced elsewheremay get garbage collected at any time, even before it’s done.

Changed in version 3.10:Removed theloop parameter.

Deprecated since version 3.10:Deprecation warning is emitted ifaw is not Future-like objectand there is no running event loop.

Timeouts

asyncio.timeout(delay)

Return anasynchronous context managerthat can be used to limit the amount of time spent waiting onsomething.

delay can either beNone, or a float/int number ofseconds to wait. Ifdelay isNone, no time limit willbe applied; this can be useful if the delay is unknown whenthe context manager is created.

In either case, the context manager can be rescheduled aftercreation usingTimeout.reschedule().

Example:

asyncdefmain():asyncwithasyncio.timeout(10):awaitlong_running_task()

Iflong_running_task takes more than 10 seconds to complete,the context manager will cancel the current task and handlethe resultingasyncio.CancelledError internally, transforming itinto aTimeoutError which can be caught and handled.

Note

Theasyncio.timeout() context manager is what transformstheasyncio.CancelledError into aTimeoutError,which means theTimeoutError can only be caughtoutside of the context manager.

Example of catchingTimeoutError:

asyncdefmain():try:asyncwithasyncio.timeout(10):awaitlong_running_task()exceptTimeoutError:print("The long operation timed out, but we've handled it.")print("This statement will run regardless.")

The context manager produced byasyncio.timeout() can berescheduled to a different deadline and inspected.

classasyncio.Timeout(when)

Anasynchronous context managerfor cancelling overdue coroutines.

when should be an absolute time at which the context should time out,as measured by the event loop’s clock:

  • Ifwhen isNone, the timeout will never trigger.

  • Ifwhen<loop.time(), the timeout will trigger on the nextiteration of the event loop.

when()float|None

Return the current deadline, orNone if the currentdeadline is not set.

reschedule(when:float|None)

Reschedule the timeout.

expired()bool

Return whether the context manager has exceeded its deadline(expired).

Example:

asyncdefmain():try:# We do not know the timeout when starting, so we pass ``None``.asyncwithasyncio.timeout(None)ascm:# We know the timeout now, so we reschedule it.new_deadline=get_running_loop().time()+10cm.reschedule(new_deadline)awaitlong_running_task()exceptTimeoutError:passifcm.expired():print("Looks like we haven't finished on time.")

Timeout context managers can be safely nested.

Added in version 3.11.

asyncio.timeout_at(when)

Similar toasyncio.timeout(), exceptwhen is the absolute timeto stop waiting, orNone.

Example:

asyncdefmain():loop=get_running_loop()deadline=loop.time()+20try:asyncwithasyncio.timeout_at(deadline):awaitlong_running_task()exceptTimeoutError:print("The long operation timed out, but we've handled it.")print("This statement will run regardless.")

Added in version 3.11.

asyncasyncio.wait_for(aw,timeout)

Wait for theawawaitableto complete with a timeout.

Ifaw is a coroutine it is automatically scheduled as a Task.

timeout can either beNone or a float or int number of secondsto wait for. Iftimeout isNone, block until the futurecompletes.

If a timeout occurs, it cancels the task and raisesTimeoutError.

To avoid the taskcancellation,wrap it inshield().

The function will wait until the future is actually cancelled,so the total wait time may exceed thetimeout. If an exceptionhappens during cancellation, it is propagated.

If the wait is cancelled, the futureaw is also cancelled.

Example:

asyncdefeternity():# Sleep for one hourawaitasyncio.sleep(3600)print('yay!')asyncdefmain():# Wait for at most 1 secondtry:awaitasyncio.wait_for(eternity(),timeout=1.0)exceptTimeoutError:print('timeout!')asyncio.run(main())# Expected output:##     timeout!

Changed in version 3.7:Whenaw is cancelled due to a timeout,wait_for waitsforaw to be cancelled. Previously, it raisedTimeoutError immediately.

Changed in version 3.10:Removed theloop parameter.

Changed in version 3.11:RaisesTimeoutError instead ofasyncio.TimeoutError.

Waiting Primitives

asyncasyncio.wait(aws,*,timeout=None,return_when=ALL_COMPLETED)

RunFuture andTask instances in theawsiterable concurrently and block until the condition specifiedbyreturn_when.

Theaws iterable must not be empty.

Returns two sets of Tasks/Futures:(done,pending).

Usage:

done,pending=awaitasyncio.wait(aws)

timeout (a float or int), if specified, can be used to controlthe maximum number of seconds to wait before returning.

Note that this function does not raiseTimeoutError.Futures or Tasks that aren’t done when the timeout occurs are simplyreturned in the second set.

return_when indicates when this function should return. It mustbe one of the following constants:

Constant

Description

asyncio.FIRST_COMPLETED

The function will return when any future finishes or is cancelled.

asyncio.FIRST_EXCEPTION

The function will return when any future finishes by raising anexception. If no future raises an exceptionthen it is equivalent toALL_COMPLETED.

asyncio.ALL_COMPLETED

The function will return when all futures finish or are cancelled.

Unlikewait_for(),wait() does not cancel thefutures when a timeout occurs.

Changed in version 3.10:Removed theloop parameter.

Changed in version 3.11:Passing coroutine objects towait() directly is forbidden.

Changed in version 3.12:Added support for generators yielding tasks.

asyncio.as_completed(aws,*,timeout=None)

Runawaitable objects in theaws iterableconcurrently. The returned object can be iterated to obtain the resultsof the awaitables as they finish.

The object returned byas_completed() can be iterated as anasynchronous iterator or a plainiterator. When asynchronousiteration is used, the originally-supplied awaitables are yielded if theyare tasks or futures. This makes it easy to correlate previously-scheduledtasks with their results. Example:

ipv4_connect=create_task(open_connection("127.0.0.1",80))ipv6_connect=create_task(open_connection("::1",80))tasks=[ipv4_connect,ipv6_connect]asyncforearliest_connectinas_completed(tasks):# earliest_connect is done. The result can be obtained by# awaiting it or calling earliest_connect.result()reader,writer=awaitearliest_connectifearliest_connectisipv6_connect:print("IPv6 connection established.")else:print("IPv4 connection established.")

During asynchronous iteration, implicitly-created tasks will be yielded forsupplied awaitables that aren’t tasks or futures.

When used as a plain iterator, each iteration yields a new coroutine thatreturns the result or raises the exception of the next completed awaitable.This pattern is compatible with Python versions older than 3.13:

ipv4_connect=create_task(open_connection("127.0.0.1",80))ipv6_connect=create_task(open_connection("::1",80))tasks=[ipv4_connect,ipv6_connect]fornext_connectinas_completed(tasks):# next_connect is not one of the original task objects. It must be# awaited to obtain the result value or raise the exception of the# awaitable that finishes next.reader,writer=awaitnext_connect

ATimeoutError is raised if the timeout occurs before all awaitablesare done. This is raised by theasyncfor loop during asynchronousiteration or by the coroutines yielded during plain iteration.

Changed in version 3.10:Removed theloop parameter.

Deprecated since version 3.10:Deprecation warning is emitted if not all awaitable objects in theawsiterable are Future-like objects and there is no running event loop.

Changed in version 3.12:Added support for generators yielding tasks.

Changed in version 3.13:The result can now be used as either anasynchronous iteratoror as a plainiterator (previously it was only a plain iterator).

Running in Threads

asyncasyncio.to_thread(func,/,*args,**kwargs)

Asynchronously run functionfunc in a separate thread.

Any *args and **kwargs supplied for this function are directly passedtofunc. Also, the currentcontextvars.Context is propagated,allowing context variables from the event loop thread to be accessed in theseparate thread.

Return a coroutine that can be awaited to get the eventual result offunc.

This coroutine function is primarily intended to be used for executingIO-bound functions/methods that would otherwise block the event loop ifthey were run in the main thread. For example:

defblocking_io():print(f"start blocking_io at{time.strftime('%X')}")# Note that time.sleep() can be replaced with any blocking# IO-bound operation, such as file operations.time.sleep(1)print(f"blocking_io complete at{time.strftime('%X')}")asyncdefmain():print(f"started main at{time.strftime('%X')}")awaitasyncio.gather(asyncio.to_thread(blocking_io),asyncio.sleep(1))print(f"finished main at{time.strftime('%X')}")asyncio.run(main())# Expected output:## started main at 19:50:53# start blocking_io at 19:50:53# blocking_io complete at 19:50:54# finished main at 19:50:54

Directly callingblocking_io() in any coroutine would block the event loopfor its duration, resulting in an additional 1 second of run time. Instead,by usingasyncio.to_thread(), we can run it in a separate thread withoutblocking the event loop.

Note

Due to theGIL,asyncio.to_thread() can typically only be usedto make IO-bound functions non-blocking. However, for extension modulesthat release the GIL or alternative Python implementations that don’thave one,asyncio.to_thread() can also be used for CPU-bound functions.

Added in version 3.9.

Scheduling From Other Threads

asyncio.run_coroutine_threadsafe(coro,loop)

Submit a coroutine to the given event loop. Thread-safe.

Return aconcurrent.futures.Future to wait for the resultfrom another OS thread.

This function is meant to be called from a different OS threadthan the one where the event loop is running. Example:

# Create a coroutinecoro=asyncio.sleep(1,result=3)# Submit the coroutine to a given loopfuture=asyncio.run_coroutine_threadsafe(coro,loop)# Wait for the result with an optional timeout argumentassertfuture.result(timeout)==3

If an exception is raised in the coroutine, the returned Futurewill be notified. It can also be used to cancel the task inthe event loop:

try:result=future.result(timeout)exceptTimeoutError:print('The coroutine took too long, cancelling the task...')future.cancel()exceptExceptionasexc:print(f'The coroutine raised an exception:{exc!r}')else:print(f'The coroutine returned:{result!r}')

See theconcurrency and multithreadingsection of the documentation.

Unlike other asyncio functions this function requires theloopargument to be passed explicitly.

Added in version 3.5.1.

Introspection

asyncio.current_task(loop=None)

Return the currently runningTask instance, orNone ifno task is running.

Ifloop isNoneget_running_loop() is used to getthe current loop.

Added in version 3.7.

asyncio.all_tasks(loop=None)

Return a set of not yet finishedTask objects run bythe loop.

Ifloop isNone,get_running_loop() is used for gettingcurrent loop.

Added in version 3.7.

asyncio.iscoroutine(obj)

ReturnTrue ifobj is a coroutine object.

Added in version 3.4.

Task Object

classasyncio.Task(coro,*,loop=None,name=None,context=None,eager_start=False)

AFuture-like object that runs a Pythoncoroutine. Not thread-safe.

Tasks are used to run coroutines in event loops.If a coroutine awaits on a Future, the Task suspendsthe execution of the coroutine and waits for the completionof the Future. When the Future isdone, the execution ofthe wrapped coroutine resumes.

Event loops use cooperative scheduling: an event loop runsone Task at a time. While a Task awaits for the completion of aFuture, the event loop runs other Tasks, callbacks, or performsIO operations.

Use the high-levelasyncio.create_task() function to createTasks, or the low-levelloop.create_task() orensure_future() functions. Manual instantiation of Tasksis discouraged.

To cancel a running Task use thecancel() method. Calling itwill cause the Task to throw aCancelledError exception intothe wrapped coroutine. If a coroutine is awaiting on a Futureobject during cancellation, the Future object will be cancelled.

cancelled() can be used to check if the Task was cancelled.The method returnsTrue if the wrapped coroutine did notsuppress theCancelledError exception and was actuallycancelled.

asyncio.Task inherits fromFuture all of itsAPIs exceptFuture.set_result() andFuture.set_exception().

An optional keyword-onlycontext argument allows specifying acustomcontextvars.Context for thecoro to run in.If nocontext is provided, the Task copies the current contextand later runs its coroutine in the copied context.

An optional keyword-onlyeager_start argument allows eagerly startingthe execution of theasyncio.Task at task creation time.If set toTrue and the event loop is running, the task will startexecuting the coroutine immediately, until the first time the coroutineblocks. If the coroutine returns or raises without blocking, the taskwill be finished eagerly and will skip scheduling to the event loop.

Changed in version 3.7:Added support for thecontextvars module.

Changed in version 3.8:Added thename parameter.

Deprecated since version 3.10:Deprecation warning is emitted ifloop is not specifiedand there is no running event loop.

Changed in version 3.11:Added thecontext parameter.

Changed in version 3.12:Added theeager_start parameter.

done()

ReturnTrue if the Task isdone.

A Task isdone when the wrapped coroutine either returneda value, raised an exception, or the Task was cancelled.

result()

Return the result of the Task.

If the Task isdone, the result of the wrapped coroutineis returned (or if the coroutine raised an exception, thatexception is re-raised.)

If the Task has beencancelled, this method raisesaCancelledError exception.

If the Task’s result isn’t yet available, this method raisesanInvalidStateError exception.

exception()

Return the exception of the Task.

If the wrapped coroutine raised an exception that exceptionis returned. If the wrapped coroutine returned normallythis method returnsNone.

If the Task has beencancelled, this method raises aCancelledError exception.

If the Task isn’tdone yet, this method raises anInvalidStateError exception.

add_done_callback(callback,*,context=None)

Add a callback to be run when the Task isdone.

This method should only be used in low-level callback-based code.

See the documentation ofFuture.add_done_callback()for more details.

remove_done_callback(callback)

Removecallback from the callbacks list.

This method should only be used in low-level callback-based code.

See the documentation ofFuture.remove_done_callback()for more details.

get_stack(*,limit=None)

Return the list of stack frames for this Task.

If the wrapped coroutine is not done, this returns the stackwhere it is suspended. If the coroutine has completedsuccessfully or was cancelled, this returns an empty list.If the coroutine was terminated by an exception, this returnsthe list of traceback frames.

The frames are always ordered from oldest to newest.

Only one stack frame is returned for a suspended coroutine.

The optionallimit argument sets the maximum number of framesto return; by default all available frames are returned.The ordering of the returned list differs depending on whethera stack or a traceback is returned: the newest frames of astack are returned, but the oldest frames of a traceback arereturned. (This matches the behavior of the traceback module.)

print_stack(*,limit=None,file=None)

Print the stack or traceback for this Task.

This produces output similar to that of the traceback modulefor the frames retrieved byget_stack().

Thelimit argument is passed toget_stack() directly.

Thefile argument is an I/O stream to which the outputis written; by default output is written tosys.stdout.

get_coro()

Return the coroutine object wrapped by theTask.

Note

This will returnNone for Tasks which have alreadycompleted eagerly. See theEager Task Factory.

Added in version 3.8.

Changed in version 3.12:Newly added eager task execution means result may beNone.

get_context()

Return thecontextvars.Context objectassociated with the task.

Added in version 3.12.

get_name()

Return the name of the Task.

If no name has been explicitly assigned to the Task, the defaultasyncio Task implementation generates a default name duringinstantiation.

Added in version 3.8.

set_name(value)

Set the name of the Task.

Thevalue argument can be any object, which is thenconverted to a string.

In the default Task implementation, the name will be visiblein therepr() output of a task object.

Added in version 3.8.

cancel(msg=None)

Request the Task to be cancelled.

If the Task is alreadydone orcancelled, returnFalse,otherwise, returnTrue.

The method arranges for aCancelledError exception to be throwninto the wrapped coroutine on the next cycle of the event loop.

The coroutine then has a chance to clean up or even deny therequest by suppressing the exception with atry ……exceptCancelledErrorfinally block.Therefore, unlikeFuture.cancel(),Task.cancel() doesnot guarantee that the Task will be cancelled, althoughsuppressing cancellation completely is not common and is activelydiscouraged. Should the coroutine nevertheless decide to suppressthe cancellation, it needs to callTask.uncancel() in additionto catching the exception.

Changed in version 3.9:Added themsg parameter.

Changed in version 3.11:Themsg parameter is propagated from cancelled task to its awaiter.

The following example illustrates how coroutines can interceptthe cancellation request:

asyncdefcancel_me():print('cancel_me(): before sleep')try:# Wait for 1 hourawaitasyncio.sleep(3600)exceptasyncio.CancelledError:print('cancel_me(): cancel sleep')raisefinally:print('cancel_me(): after sleep')asyncdefmain():# Create a "cancel_me" Tasktask=asyncio.create_task(cancel_me())# Wait for 1 secondawaitasyncio.sleep(1)task.cancel()try:awaittaskexceptasyncio.CancelledError:print("main(): cancel_me is cancelled now")asyncio.run(main())# Expected output:##     cancel_me(): before sleep#     cancel_me(): cancel sleep#     cancel_me(): after sleep#     main(): cancel_me is cancelled now
cancelled()

ReturnTrue if the Task iscancelled.

The Task iscancelled when the cancellation was requested withcancel() and the wrapped coroutine propagated theCancelledError exception thrown into it.

uncancel()

Decrement the count of cancellation requests to this Task.

Returns the remaining number of cancellation requests.

Note that once execution of a cancelled task completed, furthercalls touncancel() are ineffective.

Added in version 3.11.

This method is used by asyncio’s internals and isn’t expected to beused by end-user code. In particular, if a Task gets successfullyuncancelled, this allows for elements of structured concurrency likeTask Groups andasyncio.timeout() to continue running,isolating cancellation to the respective structured block.For example:

asyncdefmake_request_with_timeout():try:asyncwithasyncio.timeout(1):# Structured block affected by the timeout:awaitmake_request()awaitmake_another_request()exceptTimeoutError:log("There was a timeout")# Outer code not affected by the timeout:awaitunrelated_code()

While the block withmake_request() andmake_another_request()might get cancelled due to the timeout,unrelated_code() shouldcontinue running even in case of the timeout. This is implementedwithuncancel().TaskGroup context managers useuncancel() in a similar fashion.

If end-user code is, for some reason, suppressing cancellation bycatchingCancelledError, it needs to call this method to removethe cancellation state.

When this method decrements the cancellation count to zero,the method checks if a previouscancel() call had arrangedforCancelledError to be thrown into the task.If it hasn’t been thrown yet, that arrangement will berescinded (by resetting the internal_must_cancel flag).

Changed in version 3.13:Changed to rescind pending cancellation requests upon reaching zero.

cancelling()

Return the number of pending cancellation requests to this Task, i.e.,the number of calls tocancel() less the number ofuncancel() calls.

Note that if this number is greater than zero but the Task isstill executing,cancelled() will still returnFalse.This is because this number can be lowered by callinguncancel(),which can lead to the task not being cancelled after all if thecancellation requests go down to zero.

This method is used by asyncio’s internals and isn’t expected to beused by end-user code. Seeuncancel() for more details.

Added in version 3.11.