What a .env file is and why Python needs to read it
A .env file is a plain text file that stores configuration values your Python program needs — database passwords, API keys, server addresses — without writing them directly into your code. When you push your code to GitHub or share it with teammates, you do not want passwords visible in the files. The .env file stays on your machine or server only, and your Python script reads from it at startup.
Python does not read .env files automatically the way some other languages do. You have to tell Python to look for the file, find the values inside it, and load them into memory as variables your program can use. The most common way to do this is with a library called python-dotenv, which handles the reading and parsing for you.
Key Takeaways
- Install python-dotenv using pip, then import it at the top of your Python script with from dotenv import load_dotenv.
- Create a .env file in your project folder and write variables in the format KEY=value, one per line, with no spaces around the equals sign.
- Call load_dotenv() early in your script to read the .env file, then retrieve values using os.getenv("KEY_NAME").
- Add .env to your .gitignore file so the file never gets uploaded to version control and your secrets stay private.
- If your .env file is in a different folder than your script, pass the file path to load_dotenv() as an argument.
Installing python-dotenv and importing it into your script
Open your terminal or command prompt and run pip install python-dotenv. This downloads and installs the library into your Python environment. If you are working inside a virtual environment (which you should be for any real project), make sure that environment is active before you run pip.
Once installed, open your Python script and add this line at the very top, before any other imports:
from dotenv import load_dotenvimport os
You also need to import the os module because that is what you will use to retrieve the values after loading them. The os module is built into Python, so you do not need to install anything for it.
Creating and formatting your .env file
In the same folder as your Python script, create a new file and name it exactly .env — the dot at the start is required. Open it in any text editor (VS Code, Notepad, whatever you use for code) and write your variables in this format:
DATABASE_URL=postgresql://user:password@localhost/mydbAPI_KEY=abc123def456DEBUG=TrueSECRET_KEY=my-secret-key-here
Each variable goes on its own line. Use uppercase names by convention, though Python does not enforce this. Do not put quotes around the values unless the quotes are actually part of the value itself. Do not put spaces around the equals sign — KEY=value works, but KEY = value will not parse correctly.
If a value contains spaces or special characters, you can wrap it in double quotes, but this is optional for most cases. Keep the file straightforward: one variable name, one equals sign, one value per line.
Loading the .env file and reading variables in your code
After your imports, call load_dotenv() as early as possible in your script — usually right after the imports, before you define any functions or classes:
from dotenv import load_dotenvimport osload_dotenv()
This function reads the .env file and loads all the variables into your environment. Now you can retrieve any variable using os.getenv("VARIABLE_NAME"). For example:
database_url = os.getenv("DATABASE_URL")api_key = os.getenv("API_KEY")debug_mode = os.getenv("DEBUG")
The os.getenv() function returns the value as a string. If you need a boolean or number, convert it yourself: debug_mode = os.getenv("DEBUG") == "True" for a boolean, or port = int(os.getenv("PORT")) for an integer.
Handling a .env file in a different folder
If your .env file is not in the same directory as your script, pass the file path to load_dotenv(). Use a relative path from your script's location:
from dotenv import load_dotenvimport osload_dotenv("../config/.env")
Or use an absolute path if you prefer:
load_dotenv("/home/user/myproject/config/.env")
If the file does not exist at that path, load_dotenv() will not raise an error — it will just do nothing. Your script will continue running, and any call to os.getenv() for a missing variable will return None. This can be confusing to debug, so double-check your file path if variables are coming back empty.
Protecting your .env file with .gitignore
The whole point of using a .env file is to keep secrets out of version control. Create or edit a file named .gitignore in your project root (the same folder as your .env file) and add this line:
.env
This tells Git to ignore the .env file and never upload it to your repository. When someone clones your project, they will not get your passwords or API keys. Instead, they should create their own .env file locally with their own values.
If you are not using Git, this step does not explore. But if you ever plan to share your code or push it anywhere, set up .gitignore before you commit anything.
Frequently Asked Questions
What happens if a variable is not in the .env file?
os.getenv("MISSING_KEY") returns None. You can provide a default value as a second argument: os.getenv("MISSING_KEY", "default_value"). This prevents your script from breaking if a variable is missing.
Can I use .env files in a Flask or Django project?
Yes. Call load_dotenv() at the very top of your app's main file — before you import or configure anything else. In Flask, put it in your app.py or __init__.py. In Django, put it in manage.py or your settings file.
Do I need to restart my script if I change the .env file?
Yes. load_dotenv() reads the file once when your script starts. If you edit the .env file while the script is running, the changes will not take effect until you stop and restart the script.
Can I use environment variables without a .env file?
Yes. You can set environment variables directly in your terminal or system settings, and os.getenv() will read them. But a .env file is easier to manage and share across a team, so it is the standard approach for development.