> ## Documentation Index
> Fetch the complete documentation index at: https://fastapi2day.codewithsiva.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Managing Secrets with .env Files in Python Projects

> Use python-dotenv to load environment variables from a .env file, and learn the rules and patterns that keep your secrets off GitHub permanently.

A `.env` file is a plain text file that lives in your project root and holds all of your environment variables in one place. Instead of typing `export` commands every time you open a terminal, you write your configuration values once and let the `python-dotenv` library load them automatically at the start of your program. This approach is standard across the Python ecosystem — you'll see it in FastAPI projects, data science notebooks, and production services alike.

## Basic setup

<Steps>
  <Step title="Install python-dotenv">
    ```bash theme={null}
    pip install python-dotenv
    ```
  </Step>

  <Step title="Create your .env file">
    Create a file named `.env` in your project root. No extension — just `.env`:

    ```text theme={null}
    # .env
    API_KEY=sk-1234567890abcdef
    DATABASE_URL=sqlite:///myapp.db
    DEBUG=True
    ```
  </Step>

  <Step title="Load it in Python">
    ```python theme={null}
    from dotenv import load_dotenv
    import os

    # Load the .env file — call this early, before reading any variables
    load_dotenv()

    # Now read your variables normally
    api_key = os.environ.get("API_KEY")
    debug   = os.environ.get("DEBUG")

    print(f"API Key: {api_key}")
    print(f"Debug mode: {debug}")
    ```
  </Step>
</Steps>

That's all there is to it. Much easier than managing `export` commands.

## Critical rule: add .env to .gitignore

<Warning>
  **Never commit your `.env` file.** It contains real secrets. Add it to `.gitignore` before your very first commit — once a secret is in your Git history, it's there forever even if you delete the file later.

  ```text theme={null}
  # .gitignore
  .env
  .venv/
  __pycache__/
  ```
</Warning>

## Complete real-world example

Here's a realistic pattern you'll use when working with APIs:

```python theme={null}
# app.py
from dotenv import load_dotenv
import os
import requests

# Load environment variables at the top of the file
load_dotenv()

# Get the API key — fail early if it's missing
API_KEY = os.environ.get("OPENAI_API_KEY")

if not API_KEY:
    print("Error: OPENAI_API_KEY is not set in your .env file")
    exit(1)

# Use the key safely — it never appears in your source code
headers = {"Authorization": f"Bearer {API_KEY}"}
# Make your API calls...
```

Your `.env` file for this project:

```text theme={null}
# .env
OPENAI_API_KEY=sk-your-actual-key-here
MODEL=gpt-3.5-turbo
MAX_TOKENS=100
```

## Show others what variables they need

Create a companion file called `.env.example` — this one you **do** commit to Git:

```text theme={null}
# .env.example
OPENAI_API_KEY=your-api-key-here
MODEL=gpt-3.5-turbo
MAX_TOKENS=100
```

This file documents exactly what variables a new contributor needs to set up, without exposing any real values. It's a standard convention in open-source Python projects.

## Rules for .env files

* One variable per line
* No spaces around `=`
* No quotes (unless the value itself contains spaces)
* Use `#` for comments
* Names should be UPPERCASE

## Common patterns

```text theme={null}
# API Keys
OPENAI_API_KEY=sk-...
GITHUB_TOKEN=ghp_...

# Database
DATABASE_URL=sqlite:///local.db

# Application settings
DEBUG=True
PORT=8000
LOG_LEVEL=INFO
```

## Quick tips

1. **Load early** — Call `load_dotenv()` at the very top of your entry-point script, before any other imports that might read environment variables
2. **Use defaults** — `os.environ.get("PORT", "8000")` keeps your app running even when a variable isn't set
3. **Check your `.gitignore`** — Verify `.env` is listed before every new project's first push
4. **Keep it focused** — Only put values in `.env` that genuinely change between environments or need to stay secret

## What's next?

You now know how to manage secrets safely. Ready for modern Python tooling with `uv`?

<Card title="Modern Python" icon="rocket" href="/uv/index">
  Next-level Python dependency management
</Card>
