hbnetwork / python-decouple Goto Github PK
View Code? Open in Web Editor NEWStrict separation of config from code.
License: MIT License
Strict separation of config from code.
License: MIT License
Being able to set defaults is very good since I can set a local development configuration that does not require any effort from new developers to start working on the project. But Id like to be able to tell that some variables must be set in a production environment.
Here is a solution proposal that does not break the current design:
from decouple import config
DEBUG = config('DEBUG', cast=bool)
THIS_IS_REQUIRED = config('THIS_IS_REQUIRED', default='local-value', required_if=(not DEBUG))
THIS_IS_NOT_REQUIRED = config('THIS_IS_NOT_REQUIRED', default='local-value')
In this example situation, if DEBUG
is False
and the variable THIS_IS_REQUIRED
is not set, UndefinedValueError
should be raised.
If the documentation had spelled out that AutoConfig is the default and examples of RepositoryEnv/Ini that would have been helpful. Perhaps it is only a matter of adding a more few examples? For instance, if I found something like this, it would have been helpful:
from decouple import Config, RepositoryEnv
keypath = os.path.join(os.path.dirname(BASE_DIR), 'keys/.env')
config = Config(RepositoryEnv(keypath))
SECRET_KEY = config('SECRET_KEY')
Any idea/suggestion on how to effectively encrypt settings kept in the .env file, and maybe add a sort of checksum to be "reasonably" sure they haven't been tampered ?
OS: Windows 7 64 Bit
Traceback (most recent call last):
File "_pydevd_bundle\pydevd_cython_win32_35_64.pyx", line 1025, in _pydevd_bundle.pydevd_cython_win32_35_64.ThreadTracer.__call__ (_pydevd_bundle/pydevd_cython_win32_35_64.c:20043)
RecursionError: maximum recursion depth exceeded
Fatal Python error: Cannot recover from stack overflow.
Thread 0x00000fd8 (most recent call first):
File "D:\Programme\PyCharm Community Edition 2017.2.3\helpers\pydev\pydevd.py", line 98 in _on_run
File "D:\Programme\PyCharm Community Edition 2017.2.3\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 294 in run
File "D:\Programme\Python\Python35\lib\threading.py", line 914 in _bootstrap_inner
File "D:\Programme\Python\Python35\lib\threading.py", line 882 in _bootstrap
Thread 0x00001bd8 (most recent call first):
File "D:\Programme\PyCharm Community Edition 2017.2.3\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 356 in _on_run
File "D:\Programme\PyCharm Community Edition 2017.2.3\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 294 in run
File "D:\Programme\Python\Python35\lib\threading.py", line 914 in _bootstrap_inner
File "D:\Programme\Python\Python35\lib\threading.py", line 882 in _bootstrap
Thread 0x00001bd0 (most recent call first):
File "D:\Programme\Python\Python35\lib\threading.py", line 297 in wait
File "D:\Programme\Python\Python35\lib\queue.py", line 173 in get
File "D:\Programme\PyCharm Community Edition 2017.2.3\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 433 in _on_run
File "D:\Programme\PyCharm Community Edition 2017.2.3\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 294 in run
File "D:\Programme\Python\Python35\lib\threading.py", line 914 in _bootstrap_inner
File "D:\Programme\Python\Python35\lib\threading.py", line 882 in _bootstrap
Current thread 0x00000950 (most recent call first):
File "D:\Programme\Python\Python35\lib\ntpath.py", line 35 in _get_bothseps
File "D:\Programme\Python\Python35\lib\ntpath.py", line 203 in split
File "D:\Programme\Python\Python35\lib\ntpath.py", line 239 in dirname
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 170 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
File "C:\Users\user\virtenv\project\lib\site-packages\decouple.py", line 172 in _find_file
...
The Openshift Platform uses a ".env" folder, that has VARIABLE_NAME file with the value as file content, and that conflicts with decouple.
Maybe we need to create other Parser for this format, or change the .env parser.
Traceback:
File "/var/lib/openshift/558098a099fc7700aa/app-root/runtime/dependencies/python/virtenv/lib/python2.7/site-packages/decouple.py", line 196, in call
self._load(self._caller_path())
File "/var/lib/openshift/558098a099fc7700aa/app-root/runtime/dependencies/python/virtenv/lib/python2.7/site-packages/decouple.py", line 186, in _load
self.config = Config(Repository(filename))
File "/var/lib/openshift/558098a099fc7700aa/app-root/runtime/dependencies/python/virtenv/lib/python2.7/site-packages/decouple.py", line 115, in init
for line in open(source):
IOError: [Errno 21] Is a directory: '/var/lib/openshift/558098a099fc7700aa/.env'
find . -iname '*.py' | xargs -P 4 -I{} python -Wall -m py_compile {}
./tests/test_ini.py:103: SyntaxWarning: "is" with a literal. Did you mean "=="?
assert '' is config('KeyEmpty', default=None)
There is a small typo in README.rst.
Should read misbehaviours rather than misbehaviors.
.env file
####### DJANGO PARAMETERS ################
SECRET_KEY=MY_KEY
DEBUG=True
#### FILE ## NAMES ##############
DOWNLOAD_FILE=document.pdf
HTML_FILE_PATH=mydoc.htm
EXCEL_FILE_PATH=AM2.CSV
######## USER VALIDATION ##########
USER_VALID_CHECK=mathsishard
####### COLUMNS #########
COLUMNS="NAME,AD1,AD2,AD3,AD4,AD5,HOL,ENT,JT1,JT2"
####### TAGS #####
TAG1_IN_DOC_SAVED_AS_HTML=AD1
TAG2_IN_DOC_SAVED_AS_HTML=AD2
.
.
.
TAGN_IN_DOC_SAVED_AS_HTML=JT2
Now the problem is that I have a django project where I' m taking some user data through a form, using a .html file(which is a word docx saved as .html with {{ }} django tags). Further I have a csv file(database for now). In the TAGS section(plz see above) I will tell the user to put all the names of the {{ }} which he has put in the .docx file. Now my job becomes to just read the .html file and substitute all template tags with the variables by using django's render_to_string.
Problems:
First:
How to loop over all tags underneath TAGS section like a dict?
Second:
If that's not possible how to make 2 .env files(with different names obviously)?
Please help, I'm stuck badly.
Using decouple with a Django project to separate passwords from my settings.py file. I've got an element in a .env file, i.e:
SECRET_KEY=myrandompassword124$%=
Which returns:
raise UndefinedValueError('{} not found. Declare it as envvar or define a default value.'.format(option)) decouple.UndefinedValueError: SECRET_KEY not found. Declare it as envvar or define a default value.
I'm guessing the equals sign at the end of the string is throwing decouple for a loop. Any ideas on how to fix? I'd prefer not to have to change the Django key.
The Csv parsing uses shlex
and it usually escape #
beacuse it is a comment char.
Also it don't support UTF-8 chars.
@henriquebastos Do you think it's better to keep this way or change it?
I am getting key error in following command ...what is the alternative option for it..or else how should correct it ??
import os
COMPUTER_NAME = os.environ['COMPUTERNAME']
print("Computer: ", COMPUTER_NAME)
Hey, thanks for this amazing library.
I think that a option to set a prefix to environment variables is missing. You see, sometimes we have so many projects deployed on a single machine, that requires some settings between them.
Perhaps I can use Docker to handle this, but Docker requires a kernel upgrade.
Since this repository does not have a CONTRIBUTING.md
, can I implement my needs and submit a PR?
not sure how to fix this problem:
https://stackoverflow.com/questions/60733143/how-to-get-python-decouple-to-work-on-a-live-server
It would be cool if there were a way to ask the console for config input if its not set in environment or settings file.
This functionality should probably only be enabled if it detects a tty console, or maybe an INTERACTIVE=1 env var....
Anyway, this is pretty minor. If I have some free time in the near future, I'll do a PR
Wouldn't make more sense to return default value in the way it was defined?
For example, in Django, we know that ALLOWED_HOSTS is a list, but if we call config with default=[], it returns an error (using the example code in README):
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[],
cast=lambda v: [s.strip() for s in v.split(',')])
Hi, first of all, thanks for nice library! It's awesome software 👍
I need to use UTF-8 in .env and want to use python-decouple for this, but I suppose it won't work with UTF-8, because it doesn't pass encoding param to open function:
https://github.com/henriquebastos/python-decouple/blob/24cc51c7880b79d81b5a75c2d441a41428792aa6/decouple.py#L125
So it will fallback to locale.getpreferredencoding(), as specified in Python docs, which is platform dependent. On my Windows 10 its cp1251, but I want to write UTF-8 in .env and be sure it will be read correctly by python-decouple.
It would be nice, if we could pass encoding kwarg to config() and it will be used in open() (or default if this kwarg is not specified)
Feel free to notify me, if I can help with something
Hi there,
I'm have some problems when trying integrate ipython notebook on my decouple using django project. I'm using a virtualenv, so... the problem is my manage.py shell run just fine, decouple recover the values from .env file like charm, but when I'm using ipython notebook I'm getting this exception:
/home/nunesvictor/dev/sisref/env/local/lib/python2.7/site-packages/decouple.pyc in get(self, option, default, cast)
62
63 if isinstance(value, Undefined):
---> 64 raise UndefinedValueError('%s option not found and default value was not defined.' % option)
65
66 if isinstance(cast, Undefined):
UndefinedValueError: SECRET_KEY option not found and default value was not defined.```
My settings.py is configured like these:
SECRET_KEY = config('SECRET_KEY')
I wonder why decouple is incapable to get the value of my SECRET_KEY of the .env file, is this really an issue, or I'm just getting the configuration wrong?! Tks
PS. I'm using django_notebook (https://github.com/benthomasson/django_notebook)
Hi @henriquebastos,
when using
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[], cast=Csv())
I got this error:
./manage.py runserver
# ...
File "/Users/rodrigo/workspace/pmpr/megaforce/settings.py", line 30, in <module>
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[], cast=Csv())
File "/Users/rodrigo/.ve/pmpr/lib/python3.6/site-packages/decouple.py", line 197, in __call__
return self.config(*args, **kwargs)
File "/Users/rodrigo/.ve/pmpr/lib/python3.6/site-packages/decouple.py", line 77, in __call__
return self.get(*args, **kwargs)
File "/Users/rodrigo/.ve/pmpr/lib/python3.6/site-packages/decouple.py", line 71, in get
return cast(value)
File "/Users/rodrigo/.ve/pmpr/lib/python3.6/site-packages/decouple.py", line 231, in __call__
return [transform(s) for s in splitter]
File "/Users/rodrigo/.ve/pmpr/lib/python3.6/site-packages/decouple.py", line 231, in <listcomp>
return [transform(s) for s in splitter]
File "/Users/rodrigo/.pyenv/versions/3.6.1/lib/python3.6/shlex.py", line 295, in __next__
token = self.get_token()
File "/Users/rodrigo/.pyenv/versions/3.6.1/lib/python3.6/shlex.py", line 105, in get_token
raw = self.read_token()
File "/Users/rodrigo/.pyenv/versions/3.6.1/lib/python3.6/shlex.py", line 136, in read_token
nextchar = self.instream.read(1)
AttributeError: 'list' object has no attribute 'read'
On the other hand, if I put ALLOWED_HOSTS=127.0.0.1
within my .env
file, everything works fine!
Do you have any ideia what's wrong?
When decouple can't find the settings.ini it raises an error sucha as this:
/usr/local/lib/python3.5/dist-packages/decouple.py in __call__(self, *args, **kwargs)
195 self._load(self._caller_path())
196
--> 197 return self.config(*args, **kwargs)
198
199
/usr/local/lib/python3.5/dist-packages/decouple.py in __call__(self, *args, **kwargs)
75 Convenient shortcut to get.
76 """
---> 77 return self.get(*args, **kwargs)
78
79
/usr/local/lib/python3.5/dist-packages/decouple.py in get(self, option, default, cast)
62
63 if isinstance(value, Undefined):
---> 64 raise UndefinedValueError('%s option not found and default value was not defined.' % option)
65
66 if isinstance(cast, Undefined):
UndefinedValueError: PSQL_USER option not found and default value was not defined.
It would be nice if this Error message gave the user more information to fix the problem, such as where decouple has searched and not found the missing option.
It'd be nice to allow casting config to dict.. .
from decouple import config
dict_config = dict(config) # or other way of getting this result
assert dict_config['SECRET_KEY'] == config('SECRET_KEY')
Then one could easily load it to flask:
https://github.com/pallets/flask/blob/f18fe15e6d9b02631e9ff24ab3c1660b8ba28f94/flask/config.py#L198
Hey,
I was wondering what are your thoughts about extending current functionality with a possible "cast as dict" feature.
In Django for example, the 'DATABASES' setting varies from deploy to production and it is quite nice and easy (although I admit, a little brute) to just keep the entire db dict as a string in .env file
This fix makes it possible to just do:
in .env:
DATABASES={'default': {'ENGINE': 'db.backend', 'NAME': '/absolute/path/to/your/db.sqlite3',}}
and in settings.py:
DATABASES = config('DATABASES', cast=dict)
I've forked the repo and implemented the change (using literal_eval function) so am ready for PR.
What do you think?
Hi. Similarly to django-configurations, it could be very convenient to be able to specify an environment filename with variables, not just to have .env
hard-coded. For example, I could therefore specify a set of vars for different environments, e.g. prod.env, staging.env, and I could switch them using another env variable, e.g.:
DECOUPLE_CONFIGURATION=staging.env python program.py
In my settings file I have:
SECURE_PROXY_SSL_HEADER = config('SECURE_PROXY_SSL_HEADER', default=None, cast=Csv(post_process=tuple))
Now, when I want to set the header on one of my projects, everything is fine. I just put the following in my .env
file:
SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO, https
However, when I do not need this header in another project, it does not work. Because if I leave empty, the default value is None
and that conflicts with cast=Csv(post_process=tuple)
.
Trying to set value to a password email, the character "quotation mark" ( ' ) is ignore. I have research a lot but i couldn't find how to get it around
For example:
On .env:
mySMTPEmail=mypassword'
The quote character at the end of password value is ignored. I've tryied double it for closing, but anyway, when i run debugg the password value doesn't get the quote, like:
mySMTPEmail=mypassword (without quote)
So, can't authenticate on SMTP server
I've created a .env file with:
FOO=
... and when I try to get FOO
decouple raises a KeyError
exception:
$ cat .env
FOO=
BAR=1
>>> from decouple import config
>>> config("BAR")
'1'
>>> config("BAZ", "undefined")
'undefined'
>>> config("FOO", "undefined")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "decouple.py", line 190, in __call__
return self.config(*args, **kwargs)
File "decouple.py", line 73, in __call__
return self.get(*args, **kwargs)
File "decouple.py", line 55, in get
value = self.repository.get(option)
File "decouple.py", line 123, in get
return self.data.get(key) or os.environ[key]
File "/home/osantana/.virtualenvs/opinious/lib/python2.7/UserDict.py", line 23, in __getitem__
raise KeyError(key)
KeyError: 'FOO'
Hello. Something that I encountered today while adding HTTPS to my Django project:
On the python-decouple PyPI site, in the understanding the CAST argument section, the first snippet shows a Csv(tuple_=True)
class initialization, which is outdated and should be changed to Csv(post_process=tuple)
.
In the decouple.py
file, the constructor docstring has a nonexistent tuple_
parameter described, and there is no description of the post_process
parameter.
Hello, when I try to use decouple in a project, I got the following error:
from decouple import config
Error:
ImportError: cannot import name 'config' from 'decouple' (~/.local/lib/python3.7/site-packages/decouple/__init__.py)
I'm not sure what went wrong. Thanks!
What:
I think it might be interesting to offer the possibility of removing values from the environment at reading time.
Why:
In the case environment variables would be used for secret values, this would help make sure children processes do not receive those secrets. This may also help when the environment is dumped (e.g. I believe Sentry stores a copy of the process environment alongside event, though it does a bit of scrubbing). It may limit the case of involuntary secret exposure. Note: I think this does not change /proc/self/environ
, so it's not about securing against a malicious subprocess (that being said, if subprocess is launched as a different user, that might still help).
How:
https://docs.python.org/3.8/library/os.html#os.environ
If the platform supports the unsetenv() function, you can delete items in this mapping to unset environment variables. unsetenv() will be called automatically when an item is deleted from os.environ, and when one of the pop() or clear() methods is called.
Who:
If you think this can be interesting, I may be available to try and make a PR.
I am using it in my django project. Runs perfect on my local machine.
But it is causing problems when deploying on heroku,
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
utility.execute()
File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 308, in execute
settings.INSTALLED_APPS
File "/app/.heroku/python/lib/python3.6/site-packages/django/conf/__init__.py", line 56, in __getattr__
self._setup(name)
File "/app/.heroku/python/lib/python3.6/site-packages/django/conf/__init__.py", line 41, in _setup
self._wrapped = Settings(settings_module)
File "/app/.heroku/python/lib/python3.6/site-packages/django/conf/__init__.py", line 110, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File "/app/.heroku/python/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "/app/weather/settings.py", line 20, in <module>
API_KEY = config('API_KEY')
File "/app/.heroku/python/lib/python3.6/site-packages/decouple.py", line 197, in __call__
return self.config(*args, **kwargs)
File "/app/.heroku/python/lib/python3.6/site-packages/decouple.py", line 85, in __call__
return self.get(*args, **kwargs)
File "/app/.heroku/python/lib/python3.6/site-packages/decouple.py", line 70, in get
raise UndefinedValueError('{} not found. Declare it as envvar or define a default value.'.format(option))
decouple.UndefinedValueError: API_KEY not found. Declare it as envvar or define a default value.
I am getting this error when running heroku run python manage.py migrate
What should be done ?
I noticed a new Choices feature (#86) in README and source code, but 3.3 version from pypi doesn't have it :(
Could you make a release, please?
Assuming that the intended behaviour is to recursively searches up your configuration module path looking for a settings.ini
or a .env
file, given the following directory tree:
with the following content:
[settings]
SOME_VAR = value
# code.py
from decouple import config
print(config('SOME_VAR'))
# deeper_code.py
from decouple import config
print(config('SOME_VAR'))
I've tried:
$ ipython code.py
value
$ python code.py
value
$ ipython folder/deeper_code.py
value
$ python folder/deeper_code.py
Traceback (most recent call last):
File "folder/deeper_code.py", line 3, in <module>
print(config('SOME_VAR'))
File "~/.virtualenvs/decouple-test/lib/python3.4/site-packages/decouple.py", line 197, in __call__
return self.config(*args, **kwargs)
File "~/.virtualenvs/decouple-test/lib/python3.4/site-packages/decouple.py", line 77, in __call__
return self.get(*args, **kwargs)
File "~/.virtualenvs/decouple-test/lib/python3.4/site-packages/decouple.py", line 64, in get
raise UndefinedValueError('%s option not found and default value was not defined.' % option)
decouple.UndefinedValueError: SOME_VAR option not found and default value was not defined.
running ipython 4.0.0 over python 3.4.0 and python 3.4.0 alone.
Looking for some explanations, I've seen that ipython and python have a different return for the magic frame.f_back.f_back.f_code.co_filename
. The first returns an absolute path and the second a relative one.
So, as the magic depends on a function that should only be used internally, and given the behaviour described, could we replace it for something like path = os.path.abspath('.')
or add path = os.path.abspath(path)
? If so, I will be happy to offer a pull request.
First of all, thanks for this project!
I prefer to keep my .env
files inside config/
folder. I also prefer to name it differently, like prod.env
or secret.env
.
Here's a live example: https://github.com/wemake-services/wemake-django-template
Can I do that? If not, would you mind a PR for this?
Do you have any suggestions on how it should be implemented?
Cheers!
I do not have a .env file in the project folder, but I have one in a folder at the top parent directory outside of project folder. Decouple are reading this file.
/home/user/repository/
| .env # decouple should not read this file
| github/
| projects/
| myproject /
| manage.py
| myproject/
| settings.py
| urls.py
| wsgi.py
| app1/
Since last commit appears to be at least 2 years old, should I consider this project abandoned? I ask because some PRs not merged are interesting and I would use those features right away (Docker secrets being a must one right now).
The python-decouple are calling 'os.environ.get(key)', but the better approach is 'os.environ.get(key, '')', passing a empty string.
The project have a changelog file?
If not, I suggest that create one to facilitate the follow-up of version updates.
So I'm trying to use decouple but I keep getting the following error:
ImportError: cannot import name 'config' from 'decouple' (C:\Users\amng8\Desktop\Ruby\venv\lib\site-packages\decouple\__init__.py)
Any reason wy?
I am using decouple with a library I am developing.
It works just fine when I am testing it from the development directory. However after I install the library and try to import it from a python process started on a arbitrary directory, it cannot find the settings.ini even if I copy it to the directory I am starting python from.
In such cases, where should the settings.ini be placed? this should be made clear in the documentation.
There's no git tag for the 3.2 and 3.3 releases that happened in November. Can you add/push the git tags?
Also, there's nothing in the CHANGELOG about what changed.
Based on commits, I think the changes are as follows:
python-decouple 3.2:
python-decouple 3.3:
Thank you!
REDIS_HOSTS
in Django expects a list of tuples.
When I try to do this:
config('REDIS_URL', default=('127.0.0.1', 6379), cast=Csv(post_process=tuple))
I can't start my server, and this error is shown:
AttributeError: 'tuple' object has no attribute 'read'
For curious people like me who like to see testing metrics on a project's page :)
Fala Henrique, blz cara?! Cara, estou com uma dúvida em relação ao python-decouple e queria ver se você poderia responder. Minha dúvida é a seguinte: Usando o decouple vou ter minhas variáveis setadas no .ini ou .env e o decouple vai acessar esse arquivo e pegar esses valores. Até ai tudo bem, mas esse arquivo não é comitado, certo?! Nesse caso, ele ficaria na minha máquina. Como faz quando um novo dev vai desenvolver? E se eu perder esse arquivo (formatar a máquina, der algum pau sei lá). Pode parecer idiota a pergunta mas é uma pergunta que não consegui sanar. Desde já agradeço. Abraço
I run my project by python main.py
it work fine,
but I run my project by supervisor it not work.
In the Unix world settings and application parameters are usually evaluated in the following order:
python -u
)PYTHONUNBUFFERED=1
)./project/setup.cfg
)$HOME/.setup.cfg
)/etc/setup.cfg
)But python-decouple
change this order and use the .env
file settings even if we've a envvar with diferent value:
https://github.com/henriquebastos/python-decouple/blob/master/decouple.py#L127-L131
I would like to propose the following (backward incompatible) change for the method above:
def get(self, key):
try:
return os.environ[key]
except KeyError:
return self.data[key]
python-dotenv has a feature called find_dotenv()
, which -
will try to find a .env file by (a) guessing where to start using file or the working directory -- allowing this to work in non-file contexts such as IPython notebooks and the REPL, and then (b) walking up the directory tree looking for the specified file
This is specially useful for zipapps made using shiv. I don't want to package my sensitve info inside the zipapp, but python-decouple can't find my .env
when I run the zipapp, because it only looks at the __file__
, not current directory. (correct me if i'm wrong)
Thanks!
I simply want to put the idea on the table. If default
is set and cast
is not, maybe we could default to use cast = type(default)
?
Before:
DEBUG = config('DEBUG', default=False, cast=bool)
EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
After:
DEBUG = config('DEBUG', default=False)
EMAIL_PORT = config('EMAIL_PORT', default=25)
Toggling off the feature would be done by setting default=str
. But I guess this would be a breaking change. Another disadvantage is that explicit is better than implicit like the Python's Zen says. Maybe it's not clear that it will use int
if we remove cast
, for example.
I'm not happy with the idea so I'm going to close it to remove noise.
The yml support is largely used in several libs, like ansible.
The format allows very clear configuration and improve the readability.
Thanks for your work, very useful lib.
Hello,
I get warnings about ConfigParser.reafp when using decouple :
[...]\py3.7\lib\site-packages\decouple.py:106: DeprecationWarning: This method will be removed in future versions. Use 'parser.read_file()' instead.
self.parser.readfp(file_)
The warning message suggests using .read_file() instead.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.