import asyncio
from contextvars import ContextVar
active_steps = ContextVar[list[int]]("active_steps", default=None)
async def add_steps(task_name, steps):
for step in steps:
# get the active steps
current_steps = active_steps.get([])
# add a new step
current_steps.append(step) # mutates the shared list
# set the variable with the new steps
active_steps.set(current_steps)
await asyncio.sleep(0.1) # simulate async work
print(f"{task_name} final result: {active_steps.get()}")
# reset the variable with an empty array
active_steps.set([])
async def main() -> None:
requests = [add_steps("Task 1", [1, 2, 3]), add_steps("Task 2", [4, 5, 6])]
await asyncio.gather(*requests)
# Expected output:
# Task 1 final result: [1, 2, 3]
# Task 2 final result: [4, 5, 6]
if __name__ == "__main__":
asyncio.run(main())
aW1wb3J0IGFzeW5jaW8KZnJvbSBjb250ZXh0dmFycyBpbXBvcnQgQ29udGV4dFZhcgoKYWN0aXZlX3N0ZXBzID0gQ29udGV4dFZhcltsaXN0W2ludF1dKCJhY3RpdmVfc3RlcHMiLCBkZWZhdWx0PU5vbmUpCgoKYXN5bmMgZGVmIGFkZF9zdGVwcyh0YXNrX25hbWUsIHN0ZXBzKToKICAgIGZvciBzdGVwIGluIHN0ZXBzOgogICAgICAgICMgZ2V0IHRoZSBhY3RpdmUgc3RlcHMKICAgICAgICBjdXJyZW50X3N0ZXBzID0gYWN0aXZlX3N0ZXBzLmdldChbXSkKCiAgICAgICAgIyBhZGQgYSBuZXcgc3RlcAogICAgICAgIGN1cnJlbnRfc3RlcHMuYXBwZW5kKHN0ZXApICAjIG11dGF0ZXMgdGhlIHNoYXJlZCBsaXN0CgogICAgICAgICMgc2V0IHRoZSB2YXJpYWJsZSB3aXRoIHRoZSBuZXcgc3RlcHMKICAgICAgICBhY3RpdmVfc3RlcHMuc2V0KGN1cnJlbnRfc3RlcHMpCgogICAgICAgIGF3YWl0IGFzeW5jaW8uc2xlZXAoMC4xKSAgIyBzaW11bGF0ZSBhc3luYyB3b3JrCgogICAgcHJpbnQoZiJ7dGFza19uYW1lfSBmaW5hbCByZXN1bHQ6IHthY3RpdmVfc3RlcHMuZ2V0KCl9IikKICAgICMgcmVzZXQgdGhlIHZhcmlhYmxlIHdpdGggYW4gZW1wdHkgYXJyYXkKICAgIGFjdGl2ZV9zdGVwcy5zZXQoW10pCgoKYXN5bmMgZGVmIG1haW4oKSAtPiBOb25lOgogICAgcmVxdWVzdHMgPSBbYWRkX3N0ZXBzKCJUYXNrIDEiLCBbMSwgMiwgM10pLCBhZGRfc3RlcHMoIlRhc2sgMiIsIFs0LCA1LCA2XSldCiAgICBhd2FpdCBhc3luY2lvLmdhdGhlcigqcmVxdWVzdHMpCgogICAgIyBFeHBlY3RlZCBvdXRwdXQ6CiAgICAjIFRhc2sgMSBmaW5hbCByZXN1bHQ6IFsxLCAyLCAzXQogICAgIyBUYXNrIDIgZmluYWwgcmVzdWx0OiBbNCwgNSwgNl0KCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgYXN5bmNpby5ydW4obWFpbigpKQo=