# python-dotenv

[![Build Status][build_status_badge]][build_status_link]
[![PyPI version][pypi_badge]][pypi_link]

python-dotenv reads key-value pairs from a `.env` file and can set them as
environment variables. It helps in the development of applications following the
[12-factor](https://12factor.net/) principles.

- [Getting Started](#getting-started)
- [Other Use Cases](#other-use-cases)
  - [Load configuration without altering the environment](#load-configuration-without-altering-the-environment)
  - [Parse configuration as a stream](#parse-configuration-as-a-stream)
  - [Load .env files in IPython](#load-env-files-in-ipython)
- [Command-line Interface](#command-line-interface)
- [File format](#file-format)
  - [Multiline values](#multiline-values)
  - [Variable expansion](#variable-expansion)
- [Related Projects](#related-projects)
- [Acknowledgements](#acknowledgements)

## Getting Started

```shell
pip install python-dotenv
```

If your application takes its configuration from environment variables, like a
12-factor application, launching it in development is not very practical because
you have to set those environment variables yourself.

To help you with that, you can add python-dotenv to your application to make it
load the configuration from a `.env` file when it is present (e.g. in
development) while remaining configurable via the environment:

```python
from dotenv import load_dotenv

load_dotenv()  # reads variables from a .env file and sets them in os.environ

# Code of your application, which uses environment variables (e.g. from `os.environ` or
# `os.getenv`) as if they came from the actual environment.
```

By default, `load_dotenv()` will:

- Look for a `.env` file in the same directory as the Python script (or higher up the directory tree).
- Read each key-value pair and add it to `os.environ`.
- **Not override** existing environment variables (`override=False`). Pass `override=True` to override existing variables.

To configure the development environment, add a `.env` in the root directory of
your project:

```
.
├── .env
└── foo.py
```

The syntax of `.env` files supported by python-dotenv is similar to that of
Bash:

```bash
# Development settings
DOMAIN=example.org
ADMIN_EMAIL=admin@${DOMAIN}
ROOT_URL=${DOMAIN}/app
```

If you use variables in values, ensure they are surrounded with `{` and `}`,
like `${DOMAIN}`, as bare variables such as `$DOMAIN` are not expanded.

You will probably want to add `.env` to your `.gitignore`, especially if it
contains secrets like a password.

See the section "[File format](#file-format)" below for more information about what you can write in a `.env` file.

## Other Use Cases

### Load configuration without altering the environment

The function `dotenv_values` works more or less the same way as `load_dotenv`,
except it doesn't touch the environment, it just returns a `dict` with the
values parsed from the `.env` file.

```python
from dotenv import dotenv_values

config = dotenv_values(".env")  # config = {"USER": "foo", "EMAIL": "foo@example.org"}
```

This notably enables advanced configuration management:

```python
import os
from dotenv import dotenv_values

config = {
    **dotenv_values(".env.shared"),  # load shared development variables
    **dotenv_values(".env.secret"),  # load sensitive variables
    **os.environ,  # override loaded values with environment variables
}
```

### Parse configuration as a stream

`load_dotenv` and `dotenv_values` accept [streams][python_streams] via their
`stream` argument. It is thus possible to load the variables from sources other
than the filesystem (e.g. the network).

```python
from io import StringIO

from dotenv import load_dotenv

config = StringIO("USER=foo\nEMAIL=foo@example.org")
load_dotenv(stream=config)
```

### Load .env files in IPython

You can use dotenv in IPython. By default, it will use `find_dotenv` to search for a
`.env` file:

```python
%load_ext dotenv
%dotenv
```

You can also specify a path:

```python
%dotenv relative/or/absolute/path/to/.env
```

Optional flags:

- `-o` to override existing variables.
- `-v` for increased verbosity.

### Disable load_dotenv

Set `PYTHON_DOTENV_DISABLED=1` to disable `load_dotenv()` from loading .env
files or streams. Useful when you can't modify third-party package calls or in
production.

## Command-line Interface

A CLI interface `dotenv` is also included, which helps you manipulate the `.env`
file without manually opening it.

```shell
$ pip install "python-dotenv[cli]"
$ dotenv set USER foo
$ dotenv set EMAIL foo@example.org
$ dotenv list
USER=foo
EMAIL=foo@example.org
$ dotenv list --format=json
{
  "USER": "foo",
  "EMAIL": "foo@example.org"
}
$ dotenv run -- python foo.py
```

Run `dotenv --help` for more information about the options and subcommands.

## File format

The format is not formally specified and still improves over time. That being
said, `.env` files should mostly look like Bash files. Reading from FIFOs (named
pipes) on Unix systems is also supported.

Keys can be unquoted or single-quoted. Values can be unquoted, single- or
double-quoted. Spaces before and after keys, equal signs, and values are
ignored. Values can be followed by a comment. Lines can start with the `export`
directive, which does not affect their interpretation.

Allowed escape sequences:

- in single-quoted values: `\\`, `\'`
- in double-quoted values: `\\`, `\'`, `\"`, `\a`, `\b`, `\f`, `\n`, `\r`, `\t`, `\v`

### Multiline values

It is possible for single- or double-quoted values to span multiple lines. The
following examples are equivalent:

```bash
FOO="first line
second line"
```

```bash
FOO="first line\nsecond line"
```

### Variable without a value

A variable can have no value:

```bash
FOO
```

It results in `dotenv_values` associating that variable name with the value
`None` (e.g. `{"FOO": None}`. `load_dotenv`, on the other hand, simply ignores
such variables.

This shouldn't be confused with `FOO=`, in which case the variable is associated
with the empty string.

### Variable expansion

python-dotenv can interpolate variables using POSIX variable expansion.

With `load_dotenv(override=True)` or `dotenv_values()`, the value of a variable
is the first of the values defined in the following list:

- Value of that variable in the `.env` file.
- Value of that variable in the environment.
- Default value, if provided.
- Empty string.

With `load_dotenv(override=False)`, the value of a variable is the first of the
values defined in the following list:

- Value of that variable in the environment.
- Value of that variable in the `.env` file.
- Default value, if provided.
- Empty string.

## Related Projects

- [environs](https://github.com/sloria/environs)
- [Honcho](https://github.com/nickstenning/honcho)
- [dump-env](https://github.com/sobolevn/dump-env)
- [dynaconf](https://github.com/dynaconf/dynaconf)
- [parse_it](https://github.com/naorlivne/parse_it)
- [django-dotenv](https://github.com/jpadilla/django-dotenv)
- [django-environ](https://github.com/joke2k/django-environ)
- [python-decouple](https://github.com/HBNetwork/python-decouple)
- [django-configuration](https://github.com/jezdez/django-configurations)

## Acknowledgements

This project is currently maintained by [Saurabh Kumar][saurabh-homepage] and
[Bertrand Bonnefoy-Claudet][gh-bbc2] and would not have been possible without
the support of these [awesome people][contributors].

[gh-bbc2]: https://github.com/bbc2
[saurabh-homepage]: https://saurabh-kumar.com
[pypi_link]: https://badge.fury.io/py/python-dotenv
[pypi_badge]: https://badge.fury.io/py/python-dotenv.svg
[python_streams]: https://docs.python.org/3/library/io.html
[contributors]: https://github.com/theskumar/python-dotenv/graphs/contributors
[build_status_link]: https://github.com/theskumar/python-dotenv/actions/workflows/test.yml
[build_status_badge]: https://github.com/theskumar/python-dotenv/actions/workflows/test.yml/badge.svg
