getting a value from a context by name

Viewed 1000

I want to use context vars for a similar purpose like in this question and accepted answer: Context variables in Python

That corresponds to f3a() in this example:

import contextvars

user_id = contextvars.ContextVar("user_id_var")

def test():
    user_id.set("SOME-DATA")
    f2()

def f2():
    f3a()
    f3b()

def f3a():
    print(user_id.get()) 

def f3b():
    ctx = contextvars.copy_context()
    for key, value in ctx.items():
        if key.name == 'user_id_var':
            print(value)
            break

test()

However the function needs the user_id global variable to get the value. If it were in a different module, it would need to import it.

My idea was that if a function knows there exists a context and it knows the variable name, that should be all it needs. I wrote the f3b, but as you can see, I have to search all variables, because context vars do not support lookup by name. Lookup by variable is implemented, but if I had the variable, I could get the value directly from it (f3a case)

I'm afraid I do not understand why it was designed the way it was. Why an agreed-upon name is not a key? If a context is set in some kind of framework and then used by application code, those two functions will be in different modules without a common module global var. The examples I could find did not help me. Could somebody please explain the rationale behind the context vars API?

2 Answers

This is the best I worked out to make it actually make sense when I use it:

ctx = {ctx_var.name: {"context_var": ctx_var, "value": value} for ctx_var, value in copy_context().items()}

You can get the value of key user_id by this way

user_id = contextvars.ContextVar("user_id_var")
ctx = contextvars.copy_context()
ctx[user_id]
# or
ctx.get(user_id)

I saw in the official document they have mention something that might related to your concern:

The notion of "current value" deserves special consideration: different asynchronous tasks that exist and execute concurrently may have different values for the same key

and Making Context objects picklable

Related