Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 71 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
[![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
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)
- [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)
- [Multiline values](#multiline-values)
- [Variable expansion](#variable-expansion)
- [Related Projects](#related-projects)
- [Acknowledgements](#acknowledgements)

Expand All @@ -25,13 +25,13 @@ variables. It helps in the development of applications following the
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.
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:
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
Expand All @@ -46,18 +46,19 @@ 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** an environment variable that is already set, unless you explicitly pass `override=True`.
- **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:
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:
The syntax of `.env` files supported by python-dotenv is similar to that of
Bash:

```bash
# Development settings
Expand All @@ -66,22 +67,21 @@ 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.
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.
You will probably want to add `.env` to your `.gitignore`, especially if it
contains secrets like a password.

See the section "File format" below for more information about what you can write in a
`.env` file.
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.
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
Expand All @@ -104,9 +104,9 @@ config = {

### 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).
`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
Expand All @@ -119,7 +119,7 @@ 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
You can use dotenv in IPython. By default, it will use `find_dotenv` to search for a
`.env` file:

```python
Expand All @@ -140,12 +140,14 @@ Optional flags:

### 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.
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.
A CLI interface `dotenv` is also included, which helps you manipulate the `.env`
file without manually opening it.

```shell
$ pip install "python-dotenv[cli]"
Expand All @@ -166,13 +168,14 @@ 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.
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.
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:

Expand All @@ -181,8 +184,8 @@ Allowed escape sequences:

### Multiline values

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

```bash
FOO="first line
Expand All @@ -201,26 +204,27 @@ A variable can have no value:
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.
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.
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:
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:
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.
Expand All @@ -229,26 +233,27 @@ defined in the following list:

## Related Projects

- [Honcho](https://github.com/nickstenning/honcho) - For managing
Procfile-based applications.
- [django-dotenv](https://github.com/jpadilla/django-dotenv)
- [django-environ](https://github.com/joke2k/django-environ)
- [django-configuration](https://github.com/jezdez/django-configurations)
- [dump-env](https://github.com/sobolevn/dump-env)
- [environs](https://github.com/sloria/environs)
- [dynaconf](https://github.com/dynaconf/dynaconf)
- [parse_it](https://github.com/naorlivne/parse_it)
- [python-decouple](https://github.com/HBNetwork/python-decouple)
- [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](https://saurabh-kumar.com) and
[Bertrand Bonnefoy-Claudet](https://github.com/bbc2) and would not have been possible
without the support of these [awesome
people](https://github.com/theskumar/python-dotenv/graphs/contributors).
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].

[build_status_badge]: https://github.com/theskumar/python-dotenv/actions/workflows/test.yml/badge.svg
[build_status_link]: https://github.com/theskumar/python-dotenv/actions/workflows/test.yml
[pypi_badge]: https://badge.fury.io/py/python-dotenv.svg
[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