HOWTO · Python
How to Read Environment Variables From Env File in Python
Learn how to load local .env values in Python with python-dotenv or source and export them from a shell before starting a script.
On this page
A .env file stores configuration values such as a service URL or a development-mode flag. Python does not load that file automatically. For an application, the direct option is python-dotenv; a shell script is useful when you want to load and export values before starting a Python process.
Read a .env file in Python with python-dotenv
For an application, install python-dotenv in the same Python environment used to run it with python -m pip install python-dotenv. The example below creates a temporary .env file containing APP_MODE=development and passes that exact file path to load_dotenv() before retrieving the value with os.getenv(). In your application, pass the path of your project .env file to load_dotenv(); when it sits beside the script, you can use Path(__file__).with_name(".env"):
import os
from pathlib import Path
from tempfile import TemporaryDirectory
try:
from dotenv import load_dotenv
except ImportError:
print("Install python-dotenv to run this example.")
else:
with TemporaryDirectory() as directory:
env_path = Path(directory) / ".env"
env_path.write_text("APP_MODE=development\n", encoding="utf-8")
load_dotenv(env_path)
print(os.getenv("APP_MODE"))
Runtime evidence confirms the successful loading case printed development. The supplied runtime evidence also records the missing-dependency fallback, which printed “Install python-dotenv to run this example.” The example loads the temporary file created in the code, rather than a project file. By default, load_dotenv() keeps an APP_MODE value that is already present in the process environment, so development is printed only when that variable was not already set. For an application, pass the project file path explicitly as shown above. See the python-dotenv guide for package usage details.
The following self-contained standard-library example is a separate alternative for reading a simple KEY=value file without an installed package:
import os
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
env_path = Path(directory) / ".env"
env_path.write_text("APP_MODE=development\n", encoding="utf-8")
for line in env_path.read_text(encoding="utf-8").splitlines():
key, separator, value = line.partition("=")
if separator:
os.environ[key] = value
print(os.getenv("APP_MODE"))
development
This small parser is only for simple KEY=value lines; use python-dotenv when you need its .env parsing behavior. In an application, pass a path such as dotenv_path=Path(__file__).with_name(".env") to load_dotenv() when the file belongs beside your script. Keep secrets out of source control and restrict access to files that contain credentials.
Load a .env file before running Python
A shell can also load values and pass them to a Python child process. This is separate from activating a Python virtual environment: sourcing changes the shell’s variables, while a virtual environment selects Python and installed packages.
The following Bash example creates its own files, sources the configuration, exports the values for the child process, and runs Python:
set -eu
workdir=$(mktemp -d)
trap 'rm -rf "$workdir"' EXIT
cat > "$workdir/config.env" <<'ENV'
TYPE=prod
PORT=5000
ENV
cat > "$workdir/read_env.py" <<'PY'
import os
print(os.getenv("TYPE"))
print(os.getenv("PORT"))
PY
(
cd "$workdir"
set -a
. ./config.env
set +a
python3 read_env.py
)
prod
5000
Here, set -a marks assignments for export, . (the POSIX form of Bash’s source) reads the file into the current shell, and set +a turns automatic exporting back off. Sourcing executes shell syntax, so only source files you trust. A .env file intended for python-dotenv may contain syntax that is not valid shell; keep shell configuration simple and compatible with the shell you use.
If a value is missing, check that the path points to the intended file, the key spelling matches in both places, and the file is loaded before Python starts. A file being beside a script does not by itself place its values in the process environment.
Run the shell script on Windows
On Windows, run the Bash workflow through WSL or Git Bash. WSL provides a Linux distribution such as Ubuntu; Git Bash is available from the Git downloads page. In WSL, use cd to enter the directory containing run.sh; in Git Bash, choose Git Bash Here there or use cd. Then run ./run.sh. The script creates config.env and read_env.py in a temporary directory and removes them when it exits, so you do not need to place those files beside run.sh.
Save run.sh with Unix line endings (LF) so Bash can read it as expected.
Conclusion
Use python-dotenv to load a local .env file inside a Python application, or use Bash to source and export shell-compatible values before starting Python. Check the file path and variable names first when a value is unavailable, and remember that sourcing executes the file as shell code.