Python ignoring sourced .env file

Viewed 411

I'm confused about the significance of source .env and why Python is not accessing those variables although those variables are accessible from bash.

When I manual export FOO=foo, Python sees the env, but not when I source .env

$ cat .env 
ENV=development
$ echo $ENV

$ echo $FOO

$ source .env 
$ export FOO=foo
$ echo $ENV
development
$ echo $FOO
foo
$ python3
Python 3.7.7 (default, Mar 10 2020, 15:43:27)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> print(os.getenv("ENV"))
None
>>> print(os.getenv("FOO"))
foo
2 Answers

I'm confused about the significance of source .env

source just works like "include" in other languages, like in C it includes the content of other file. source just parses the text from other file as-if it would be typed in.

Why Python is not accessing those variables although those variables are accessible from bash.

Because the variable is not exported, when the execution environment for python process is created, the value of that variable is not included in that environment.

So how would I easily go about exporting all key-value vars in an .env file?

  • Add export to each variable in .env file, or
  • Use set -a to export all variables and then source the file, or
  • Parse the .env file to extract variable names and set the export attribute on each variable with export.

As KamilCuk said, source does not necessary "export". Variables must be exported, not just sources, so in my case I would just have export ENV=development in the .env file and source that.

Notice in this case .env is different on line 2.

$ cat .env 
export ENV=development
$ echo $ENV

$ echo $FOO

$ source .env 
$ export FOO=foo
$ echo $ENV
development
$ echo $FOO
foo
$ python3
Python 3.7.7 (default, Mar 10 2020, 15:43:27) 
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> print(os.getenv("ENV"))
development
>>> print(os.getenv("FOO"))
foo

And to add to this, when I did export FOO=foo, this both assigns and exports, but in fact if you were to just do the following, you would create a bash var without export.

$ FOO=foo
$ echo $FOO
foo

In this case it's assigned, but not exported. Python needs it to be exported.

Related