|
| 1 | +``` |
| 2 | + _______ .__ __. ____ ____ |
| 3 | + | ____|| \ | | \ \ / / |
| 4 | + | |__ | \| | \ \/ / |
| 5 | + | __| | . ` | \ / |
| 6 | + __ | |____ | |\ | \ / |
| 7 | + (__)|_______||__| \__| \__/ |
| 8 | +``` |
| 9 | +python-dotenv | [](https://travis-ci.org/theskumar/python-dotenv) [](https://coveralls.io/r/theskumar/python-dotenv?branch=master) [](http://badge.fury.io/py/python-dotenv) [](http://badge.fury.io/py/python-dotenv) |
| 10 | +=============================================================================== |
| 11 | + |
| 12 | +Reads the key,value pair from `.env` file and adds them to environment |
| 13 | +variable. It is great for managing app settings during development and |
| 14 | +in production using [12-factor](http://12factor.net/) principles. |
| 15 | + |
| 16 | +> Do one thing, do it well! |
| 17 | +
|
| 18 | +- [Usages](#usages) |
| 19 | +- [Installation](#installation) |
| 20 | +- [Command-line interface](#command-line-interface) |
| 21 | +- [iPython Support](#ipython-support) |
| 22 | +- [Setting config on remote servers](#setting-config-on-remote-servers) |
| 23 | +- [Related Projects](#related-projects) |
| 24 | +- [Contributing](#contributing) |
| 25 | +- [Changelog](#changelog) |
| 26 | + |
| 27 | +Usages |
| 28 | +====== |
| 29 | + |
| 30 | +The easiest and most common usage consists on calling `load_dotenv` when |
| 31 | +the application starts, which will load environment variables from a |
| 32 | +file named `.env` in the current directory or any of its parents or from |
| 33 | +the path specificied; after that, you can just call the |
| 34 | +environment-related method you need as provided by `os.getenv`. |
| 35 | + |
| 36 | +`.env` looks like this: |
| 37 | + |
| 38 | +```shell |
| 39 | +# a comment and that will be ignored. |
| 40 | +REDIS_ADDRESS=localhost:6379 |
| 41 | +MEANING_OF_LIFE=42 |
| 42 | +MULTILINE_VAR="hello\nworld" |
| 43 | +``` |
| 44 | + |
| 45 | +You can optionally prefix each line with the word `export`, which will |
| 46 | +conveniently allow you to source the whole file on your shell. |
| 47 | + |
| 48 | +`.env` can interpolate variables using POSIX variable expansion, |
| 49 | +variables are replaced from the environment first or from other values |
| 50 | +in the `.env` file if the variable is not present in the environment. |
| 51 | +(`Note`: Default Value Expansion is not supported as of yet, see |
| 52 | +[\#30](https://github.com/theskumar/python-dotenv/pull/30#issuecomment-244036604).) |
| 53 | + |
| 54 | +```shell |
| 55 | +CONFIG_PATH=${HOME}/.config/foo |
| 56 | +DOMAIN=example.org |
| 57 | +EMAIL=admin@${DOMAIN} |
| 58 | +``` |
| 59 | + |
| 60 | +Getting started |
| 61 | +=============== |
| 62 | + |
| 63 | +Assuming you have created the `.env` file along-side your settings |
| 64 | +module. |
| 65 | + |
| 66 | + . |
| 67 | + ├── .env |
| 68 | + └── settings.py |
| 69 | + |
| 70 | +Add the following code to your `settings.py` |
| 71 | + |
| 72 | +```python |
| 73 | +# settings.py |
| 74 | +from dotenv import load_dotenv |
| 75 | +load_dotenv() |
| 76 | + |
| 77 | +# OR, the same with increased verbosity: |
| 78 | +load_dotenv(verbose=True) |
| 79 | + |
| 80 | +# OR, explicitly providing path to '.env' |
| 81 | +from pathlib import Path # python3 only |
| 82 | +env_path = Path('.') / '.env' |
| 83 | +load_dotenv(dotenv_path=env_path) |
| 84 | +``` |
| 85 | + |
| 86 | +At this point, parsed key/value from the .env file is now present as |
| 87 | +system environment variable and they can be conveniently accessed via |
| 88 | +`os.getenv()` |
| 89 | + |
| 90 | +```python |
| 91 | +# settings.py |
| 92 | +import os |
| 93 | +SECRET_KEY = os.getenv("EMAIL") |
| 94 | +DATABASE_PASSWORD = os.getenv("DATABASE_PASSWORD") |
| 95 | +``` |
| 96 | + |
| 97 | +`load_dotenv` do not override existing System environment variables. To |
| 98 | +override, pass `override=True` to `load_dotenv()`. |
| 99 | + |
| 100 | +You can use `find_dotenv()` method that will try to find a `.env` file |
| 101 | +by (a) guessing where to start using `__file__` or the working directory |
| 102 | +-- allowing this to work in non-file contexts such as IPython notebooks |
| 103 | +and the REPL, and then (b) walking up the directory tree looking for the |
| 104 | +specified file -- called `.env` by default. |
| 105 | + |
| 106 | +```python |
| 107 | +from dotenv import load_dotenv, find_dotenv |
| 108 | +load_dotenv(find_dotenv()) |
| 109 | +``` |
| 110 | + |
| 111 | +In-memory filelikes |
| 112 | +------------------- |
| 113 | + |
| 114 | +It is possible to not rely on the filesystem to parse filelikes from |
| 115 | +other sources (e.g. from a network storage). `load_dotenv` and |
| 116 | +`dotenv_values` accepts a filelike `stream`. Just be sure to rewind it |
| 117 | +before passing. |
| 118 | + |
| 119 | +```python |
| 120 | +>>> from io import StringIO # Python2: from StringIO import StringIO |
| 121 | +>>> from dotenv import dotenv_values |
| 122 | +>>> filelike = StringIO('SPAM=EGSS\n') |
| 123 | +>>> filelike.seek(0) |
| 124 | +>>> parsed = dotenv_values(stream=filelike) |
| 125 | +>>> parsed['SPAM'] |
| 126 | +'EGSS' |
| 127 | +``` |
| 128 | + |
| 129 | +The returned value is dictionary with key value pair. |
| 130 | + |
| 131 | +`dotenv_values` could be useful if you need to *consume* the envfile but |
| 132 | +not *apply* it directly into the system environment. |
| 133 | + |
| 134 | +Django |
| 135 | +------ |
| 136 | + |
| 137 | +If you are using django you should add the above loader script at the |
| 138 | +top of `wsgi.py` and `manage.py`. |
| 139 | + |
| 140 | +Installation |
| 141 | +============ |
| 142 | + |
| 143 | + pip install -U python-dotenv |
| 144 | + |
| 145 | +iPython Support |
| 146 | +--------------- |
| 147 | + |
| 148 | +You can use dotenv with iPython. You can either let the dotenv search |
| 149 | +for .env with %dotenv or provide the path to .env file explicitly, see |
| 150 | +below for usages. |
| 151 | + |
| 152 | + %load_ext dotenv |
| 153 | + |
| 154 | + # Use find_dotenv to locate the file |
| 155 | + %dotenv |
| 156 | + |
| 157 | + # Specify a particular file |
| 158 | + %dotenv relative/or/absolute/path/to/.env |
| 159 | + |
| 160 | + # Use '-o' to indicate override of existing variables |
| 161 | + %dotenv -o |
| 162 | + |
| 163 | + # Use '-v' to turn verbose mode on |
| 164 | + %dotenv -v |
| 165 | + |
| 166 | +Command-line interface |
| 167 | +====================== |
| 168 | + |
| 169 | +For commandline support, use the cli option during installation: |
| 170 | + |
| 171 | + pip install -U "python-dotenv[cli]" |
| 172 | + |
| 173 | +A cli interface `dotenv` is also included, which helps you manipulate |
| 174 | +the `.env` file without manually opening it. The same cli installed on |
| 175 | +remote machine combined with fabric (discussed later) will enable you to |
| 176 | +update your settings on remote server, handy isn't it! |
| 177 | + |
| 178 | +``` |
| 179 | +Usage: dotenv [OPTIONS] COMMAND [ARGS]... |
| 180 | +
|
| 181 | + This script is used to set, get or unset values from a .env file. |
| 182 | +
|
| 183 | +Options: |
| 184 | + -f, --file PATH Location of the .env file, defaults to .env |
| 185 | + file in current working directory. |
| 186 | + -q, --quote [always|never|auto] |
| 187 | + Whether to quote or not the variable values. |
| 188 | + Default mode is always. This does not affect |
| 189 | + parsing. |
| 190 | + --help Show this message and exit. |
| 191 | +
|
| 192 | +Commands: |
| 193 | + get Retrive the value for the given key. |
| 194 | + list Display all the stored key/value. |
| 195 | + set Store the given key/value. |
| 196 | + unset Removes the given key. |
| 197 | +``` |
| 198 | + |
| 199 | +Setting config on remote servers |
| 200 | +-------------------------------- |
| 201 | + |
| 202 | +We make use of excellent [Fabric](http://www.fabfile.org/) to acomplish |
| 203 | +this. Add a config task to your local fabfile, `dotenv_path` is the |
| 204 | +location of the absolute path of `.env` file on the remote server. |
| 205 | + |
| 206 | +```python |
| 207 | +# fabfile.py |
| 208 | + |
| 209 | +import dotenv |
| 210 | +from fabric.api import task, run, env |
| 211 | + |
| 212 | +# absolute path to the location of .env on remote server. |
| 213 | +env.dotenv_path = '/opt/myapp/.env' |
| 214 | + |
| 215 | +@task |
| 216 | +def config(action=None, key=None, value=None): |
| 217 | + '''Manage project configuration via .env |
| 218 | +
|
| 219 | + e.g: fab config:set,<key>,<value> |
| 220 | + fab config:get,<key> |
| 221 | + fab config:unset,<key> |
| 222 | + fab config:list |
| 223 | + ''' |
| 224 | + run('touch %(dotenv_path)s' % env) |
| 225 | + command = dotenv.get_cli_string(env.dotenv_path, action, key, value) |
| 226 | + run(command) |
| 227 | +``` |
| 228 | + |
| 229 | +Usage is designed to mirror the heroku config api very closely. |
| 230 | + |
| 231 | +Get all your remote config info with `fab config` |
| 232 | + |
| 233 | + $ fab config |
| 234 | + foo="bar" |
| 235 | + |
| 236 | +Set remote config variables with `fab config:set,<key>,<value>` |
| 237 | + |
| 238 | + $ fab config:set,hello,world |
| 239 | + |
| 240 | +Get a single remote config variables with `fab config:get,<key>` |
| 241 | + |
| 242 | + $ fab config:get,hello |
| 243 | + |
| 244 | +Delete a remote config variables with `fab config:unset,<key>` |
| 245 | + |
| 246 | + $ fab config:unset,hello |
| 247 | + |
| 248 | +Thanks entirely to fabric and not one bit to this project, you can chain |
| 249 | +commands like so |
| 250 | +`fab config:set,<key1>,<value1> config:set,<key2>,<value2>` |
| 251 | + |
| 252 | + $ fab config:set,hello,world config:set,foo,bar config:set,fizz=buzz |
| 253 | + |
| 254 | +Related Projects |
| 255 | +================ |
| 256 | + |
| 257 | +- [Honcho](https://github.com/nickstenning/honcho) - For managing |
| 258 | + Procfile-based applications. |
| 259 | +- [django-dotenv](https://github.com/jpadilla/django-dotenv) |
| 260 | +- [django-environ](https://github.com/joke2k/django-environ) |
| 261 | +- [django-configuration](https://github.com/jezdez/django-configurations) |
| 262 | +- [dump-env](https://github.com/sobolevn/dump-env) |
| 263 | + |
| 264 | +Contributing |
| 265 | +============ |
| 266 | + |
| 267 | +All the contributions are welcome! Please open [an |
| 268 | +issue](https://github.com/theskumar/python-dotenv/issues/new) or send us |
| 269 | +a pull request. |
| 270 | + |
| 271 | +This project is currently maintained by Saurabh Kumar\_ and would not |
| 272 | +have been possible without the support of these [awesome |
| 273 | +people](https://github.com/theskumar/python-dotenv/graphs/contributors). |
| 274 | + |
| 275 | +Executing the tests: |
| 276 | + |
| 277 | + $ flake8 |
| 278 | + $ pytest |
| 279 | + |
| 280 | +Changelog |
| 281 | +========= |
| 282 | + |
| 283 | +0.8.1 |
| 284 | +----- |
| 285 | + |
| 286 | +- Add tests for docs ([@Flimm]) |
| 287 | +- Make 'cli' support optional. Use `pip install python-dotnev[cli]`. ([@theskumar]) |
| 288 | + |
| 289 | +0.8.0 |
| 290 | +----- |
| 291 | + |
| 292 | +- `set_key` and `unset_key` only modified the affected file instead of |
| 293 | + parsing and re-writing file, this causes comments and other file |
| 294 | + entact as it is. |
| 295 | +- Add support for `export` prefix in the line. |
| 296 | +- Internal refractoring ([@theskumar]) |
| 297 | +- Allow `load_dotenv` and `dotenv_values` to work with `StringIO())` ([@alanjds])([@theskumar])([#78]) |
| 298 | + |
| 299 | +0.7.1 |
| 300 | +----- |
| 301 | + |
| 302 | +- Remove hard dependency on iPython ([@theskumar]) |
| 303 | + |
| 304 | +0.7.0 |
| 305 | +----- |
| 306 | + |
| 307 | +- Add support to override system environment variable via .env. |
| 308 | + ([@milonimrod](https://github.com/milonimrod)) |
| 309 | + ([\#63](https://github.com/theskumar/python-dotenv/issues/63)) |
| 310 | +- Disable ".env not found" warning by default |
| 311 | + ([@maxkoryukov](https://github.com/maxkoryukov)) |
| 312 | + ([\#57](https://github.com/theskumar/python-dotenv/issues/57)) |
| 313 | + |
| 314 | +0.6.5 |
| 315 | +----- |
| 316 | + |
| 317 | +- Add support for special characters `\`. |
| 318 | + ([@pjona](https://github.com/pjona)) |
| 319 | + ([\#60](https://github.com/theskumar/python-dotenv/issues/60)) |
| 320 | + |
| 321 | +0.6.4 |
| 322 | +----- |
| 323 | + |
| 324 | +- Fix issue with single quotes ([@Flimm]) |
| 325 | + ([\#52](https://github.com/theskumar/python-dotenv/issues/52)) |
| 326 | + |
| 327 | +0.6.3 |
| 328 | +----- |
| 329 | + |
| 330 | +- Handle unicode exception in setup.py |
| 331 | + ([\#46](https://github.com/theskumar/python-dotenv/issues/46)) |
| 332 | + |
| 333 | +0.6.2 |
| 334 | +----- |
| 335 | + |
| 336 | +- Fix dotenv list command ([@ticosax](https://github.com/ticosax)) |
| 337 | +- Add iPython Suport |
| 338 | + ([@tillahoffmann](https://github.com/tillahoffmann)) |
| 339 | + |
| 340 | +0.6.0 |
| 341 | +----- |
| 342 | + |
| 343 | +- Drop support for Python 2.6 |
| 344 | +- Handle escaped charaters and newlines in quoted values. (Thanks |
| 345 | + [@iameugenejo](https://github.com/iameugenejo)) |
| 346 | +- Remove any spaces around unquoted key/value. (Thanks |
| 347 | + [@paulochf](https://github.com/paulochf)) |
| 348 | +- Added POSIX variable expansion. (Thanks |
| 349 | + [@hugochinchilla](https://github.com/hugochinchilla)) |
| 350 | + |
| 351 | +0.5.1 |
| 352 | +----- |
| 353 | + |
| 354 | +- Fix find\_dotenv - it now start search from the file where this |
| 355 | + function is called from. |
| 356 | + |
| 357 | +0.5.0 |
| 358 | +----- |
| 359 | + |
| 360 | +- Add `find_dotenv` method that will try to find a `.env` file. |
| 361 | + (Thanks [@isms](https://github.com/isms)) |
| 362 | + |
| 363 | +0.4.0 |
| 364 | +----- |
| 365 | + |
| 366 | +- cli: Added `-q/--quote` option to control the behaviour of quotes |
| 367 | + around values in `.env`. (Thanks |
| 368 | + [@hugochinchilla](https://github.com/hugochinchilla)). |
| 369 | +- Improved test coverage. |
| 370 | + |
| 371 | +[#78]: https://github.com/theskumar/python-dotenv/issues/78 |
| 372 | + |
| 373 | +[@Flimm]: https://github.com/Flimm |
| 374 | +[@theskumar]: https://github.com/theskumar |
| 375 | +[@alanjds]: https://github.com/alanjds |
0 commit comments