0

I have the following code across different files. I want to understand what is the best practice to define the global variable so that I don't have to run the function again to get the variable value. File structure as below:

00.py

def f_token():
    global v_Token, v_session
    auth_context = adal.AuthenticationContext("https://login.microsoftonline.com/common")
    token_response = auth_context.acquire_token_with_username_password("https://xxx.xxx.dynamics.com/", username, password, client_id)
    v_Token= token_response['accessToken']
    return v_Token

01.py

from 00 import*
A_Token = f_token()
def f_meta():
    code here

02.py

from 00 import*
A_Token = f_token()
def f_anotherfunction():
    code here

03.py

from 00 import*
A_Token = f_token()
def f_function():
    code here

I only want to execute f_token once and reuse the value of v_Token across file 01,02, and 03. These 3 functions are not dependant on each other. They are being executed separately. What would be the best practice for this problem?

  • Maybe or maybe not best practise (that's out of scope for SO anyway), but a [Singleton Pattern](https://stackoverflow.com/q/6760685/1270789) is one way to address this issue. – Ken Y-N May 10 '23 at 04:02

2 Answers2

1

Assuming this code could be multithreaded, you can control access to the global variable with a lock. The global resource starts out None and the first caller who finds that None acquires the token. Future callers notice it is no longer None and skip the extra work.

import threading

v_lock = threading.Lock()
v_Token = v_session = None

def f_token():
    global v_Token, v_session
    # short circuit when token already acquired 
    if not v_Token:
        # lock, verify no race condition, get token
        with v_lock.lock():
            if v_Token is None:    
                auth_context = adal.AuthenticationContext("https://login.microsoftonline.com/common")
                token_response = auth_context.acquire_token_with_username_password("https://xxx.xxx.dynamics.com/", username, password, client_id)
                v_Token = token_response['accessToken']
    return v_Token

You probably don't want those module level A_Token = f_token() calls in other modules. Simple import generally shouldn't do something as dramatic as network authentication. It makes things hard to test and code is generally less reusable. Just call f_token() every time you need the token.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
0

Save the value as a top-level (i.e. global) variable in a module.

module_A.py
-----------
A = something(...)

Then other modules can import that variable:

module_B.py
-----------
from module_A import A


module_C.py
-----------
from module_A import A

The something() function inside module_A.py is only executed the first time it is imported.

John Gordon
  • 29,573
  • 7
  • 33
  • 58