I have a .env
defined with the following content:
env=loc
I have three python module that make use of this variable.
├── __init__.py
├── cli.py
|── settings.py
├── commands
│ ├── __init__.py
│ └── output.py
settings.py:
from dotenv import load_dotenv
load_dotenv()
if not os.getenv("env"):
raise TypeError("'env' variable not found in .env file")
output.py:
import os
def output():
return getenv("env")
cli.py
:
import settings
from commands.output import output
import os
CURR_ENV = getenv("env")
print(CURR_ENV)
print(output())
Output:
loc
None
Why is the output from output.py
not loc? The environment variables were loaded when load_dotenv() was run for the first time.
Do I have to run load_dotenv() every time I need to access the environment variables?
This answer more or less repeats what's mentioned in the comments and adds a demo example.
Once load_dotenv()
is called, environment variables will be visible in the process it's called in (and in any child process) from that point.
Suppose you have a project organized as follows.
├── commands
│ ├── __init__.py
│ └── output.py
├── __init__.py
├── .env
├── main.py
|── settings.py
settings.py
:
from os import getenv
print("From settings.py:", getenv("env"))
output.py
:
from os import getenv
def output():
print("From output.py:", getenv("env"))
output()
main.py
:
from os import getenv
from dotenv import load_dotenv
import settings # <-- settings don't see .env yet
from commands.output import output # <-- output don't see .env yet
load_dotenv() # <-- because load_dotenv is called here
print("From main.py:", getenv("env"))
output() # <--- the function call is made after load_dotenv(), so .env is visible
So if you run main.py
in the CLI, you'll get the following output.
PS path\to\module> python .\main.py
From settings.py: None
From output.py: None
From main.py: loc
From output.py: loc
To make .env visible everywhere, move load_dotenv
logic before any of the imports in main.py
or make a call to load_dotenv
inside the first import (in this example, settings.py
) instead of main.py
because every line in settings.py
will be read once it's imported so every import and function call in it will be read in main.py
anyway.
In the above example of executing main.py
, .env became visible when calling the output()
function inside main.py
because it was called after the call to load_dotenv
. That means, if you want to execute output.py
by itself, you'll need to import load_dotenv
and make a call to it inside output.py
in order for it to see the environment variables. This becomes somewhat useful if you have a test/ directory in your module and want to execute some file from there.