How to run a coroutine inside a context?

2024/9/20 20:31:40

In the Python docs about Context Vars a Context::run method is described to enable executing a callable inside a context so changes that the callable perform to the context are contained inside the copied Context. Though what if you need to execute a coroutine? What are you supposed to do in order to achieve the same behavior?

In my case, what I wanted was something like this to handle a transactional context with possible nested transactions:

my_ctxvar = ContextVar("my_ctxvar")async def coro(func, transaction):token = my_ctxvar.set(transaction)r = await func()my_ctxvar.reset(token)  # no real need for this, but why not eitherreturn rasync def foo():ctx = copy_context()# simplification to one case here: let's use the current transaction if there is oneif tx_owner := my_ctxvar not in ctx:tx = await create_transaction()else:tx = my_ctxvar.get()try:r = await ctx.run(coro)  # not actually possibleif tx_owner:await tx.commit()except Exception as e:if tx_owner:await tx.rollback()raise from ereturn r
Answer

As I already pointed out here, context variables are natively supported by asyncio and are ready to be used without any extra configuration. It should be noted that:

  • Сoroutines executed by the current task by means of await share the same context
  • New spawned tasks by create_task are executed in the copy of parent task context.

Therefore, in order to execute a coroutine in a copy of the current context, you can execute it as a task:

await asyncio.create_task(coro())

Small example:

import asyncio
from contextvars import ContextVarvar = ContextVar('var')async def foo():await asyncio.sleep(1)print(f"var inside foo {var.get()}")var.set("ham")  # change copyasync def main():var.set('spam')await asyncio.create_task(foo())print(f"var after foo {var.get()}")asyncio.run(main())
var inside foo spam
var after foo spam
https://en.xdnf.cn/q/72128.html

Related Q&A

Random Forest interpretation in scikit-learn

I am using scikit-learns Random Forest Regressor to fit a random forest regressor on a dataset. Is it possible to interpret the output in a format where I can then implement the model fit without using…

Why are three apostrophes needed for print in Python?

Im making this Pythagoras Theorem Calculator in Python 3.3.2.I made print over several lines so that I could make a diagram:print("Welcome to the Pythagoras Theorem Calculator, powered by Python!&…

Downloading files from public Google Drive in python: scoping issues?

Using my answer to my question on how to download files from a public Google drive I managed in the past to download images using their IDs from a python script and Google API v3 from a public drive us…

Change locale for django-admin-tools

In my settings.py file I have:LANGUAGE_CODE = ru-RUalso, I have installed and working django-admin-tools. But admin language still english. What Im doing wrong?PS.$ cat settings.py | grep USE | grep -…

Container localhost does not exist error when using Keras + Flask Blueprints

I am trying to serve a machine learning model via an API using Flasks Blueprints, here is my flask __init__.py filefrom flask import Flaskdef create_app(test_config=None):app = Flask(__name__)@app.rout…

Serving static files with WSGI and Python 3

What is the simplest way to serve static files with WSGI and Python 3.2? There are some WSGI apps for PEP 333 and Python 2 for this purpose - but was is about PEP 3333 and Python 3? I want to use wsg…

Force INNER JOIN for Django Query

Here is my schema:City PhotographerIm trying to get a list of cities that have at least one photographer, and return the photographer count for the cities.Here is the queryset Im working with:City.obj…

Sklearn Decision Rules for Specific Class in Decision tree

I am creating a decision tree.My data is of the following typeX1 |X2 |X3|.....X50|Y _____________________________________ 1 |5 |7 |.....0 |1 1.5|34 |81|.....0 |1 4 |21 |21|.... 1 |0 65 |34 |23|..…

Cubic hermit spline interpolation python

I would like to calculate a third-degree polynomial that is defined by its function values and derivatives at specified points.https://en.wikipedia.org/wiki/Cubic_Hermite_splineI know of scipys interpo…

Increase Accuracy of float division (python)

Im writing a bit of code in PyCharm, and I want the division to be much more accurate than it currently is (40-50 numbers instead of about 15). How Can I accomplish this?Thanks.