pythonvisual-studio-codejupyter-notebookenvironment-variables

update env variable on notebook in VsCode


I’m working on a python project with a notebook and .env file on VsCode. I have problem when trying to refresh environment variables in a notebook (I found a way but it's super tricky).

My project:

.env file with: MY_VAR="HELLO_ALICE"

test.ipynb file with one cell:

from os import environ
print('MY_VAR = ', environ.get('MY_VAR'))

What I want:

  1. set the env variable and run my notebook (see HELLO_ALICE)
  2. edit .env file: change "HELLO_ALICE" to "HELLO_BOB"
  3. set the env variable and run my notebook (see HELLO_BOB)

What do not work:

  1. open my project in vsCode, open terminal
  2. in terminal run: >> set -a; source .env; set +a;
  3. open notebook, run cell --> I see HELLO_ALICE
  4. edit .env (change HELLO_ALICE TO HELLO_BOB)
  5. restart notebook (either click on restart or close tab and reopen it)
  6. in terminal run: >> set -a; source .env; set +a; (same as step 2)
  7. open notebook, run cell --> I see HELLO_ALICE

So I see twice HELLO_ALICE instead of HELLO_ALICE then HELLO_BOB...

But if it was on .py file instead of notebook, it would have worked (I would see HELLO_ALICE first then HELLO_BOB)

To make it work:

Replace step 5. by: Close VsCode and reopen it

Why it is a problem:

It is super tricky. I'm sure that in 3 month I will have forgotten this problem with the quick fix and I will end up loosing again half a day to figure out what is the problem & solution.

So my question is:

Does anyone know why it works like this and how to avoid closing and reopening VsCode to refresh env variable stored in a .env file on a notebook ?

(Closing and reopening VsCode should not change behavior of code)

Notes:


Solution

  • The terminal you open in VSC is not the same terminal ipython kernel is running. The kernel is already running in an environment that is not affected by you changing variables in another terminal. You need to set the variables in the correct environment. You can do that with dotenv, but remember to use override=True.

    This seems to work:

    $ pip3 install python-dotenv
    
    import dotenv
    from os import environ
    env_file = '../.env'
    
    f = open(env_file,'w')
    f.write('MY_VAR="HELLO_ALICE"')
    f.close()
    dotenv.load_dotenv(env_file, override=True)
    print('MY_VAR = ', environ.get('MY_VAR'))
    
    f = open(env_file,'w')
    f.write('MY_VAR="HELLO_BOB"')
    f.close()
    dotenv.load_dotenv(env_file, override=True)
    print('MY_VAR = ', environ.get('MY_VAR'))
    
    MY_VAR =  HELLO_ALICE
    MY_VAR =  HELLO_BOB