Giter Club home page Giter Club logo

python-decouple's People

Contributors

0xc4n1 avatar 3vilwind avatar b0o avatar blueyed avatar danielgoncalves avatar flavioamieiro avatar henriquebastos avatar ibachar-es avatar iurisilvio avatar jayennis22 avatar jonafato avatar kianmeng avatar kivs avatar kojiromike avatar lpmi-13 avatar lucaspolo avatar lucasrcezimbra avatar luzfcb avatar mehrh8 avatar mjr avatar osantana avatar pietrodn avatar rmax avatar stevejalim avatar thiagogds avatar timgates42 avatar tirkarthi avatar willkg avatar xmnlab avatar zandorsabino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-decouple's Issues

Conditional required variables proposal

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.

More documentation/examples using RepositoryEnv, RepositoryIni

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')

Settings encryption

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 ?

not finding settings file causes stack overflow on windows

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
  ...

Problem with Openshift Platform and .env folder

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'

How to loop through python-decouple variables?

.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.

= Symbol Breaking Decouple

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.

About getting key error in foolowing command

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)

Option to set a prefix to environment variables

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?

Feature Request / Console input

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

Config.get returning default value without cast(value)

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(',')])

UTF-8 support in .env

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

Compatibility problems with ipython notebook

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)

empty list as default for Csv() parser.

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?

Show ini or env being used when raising UndefinedValueError

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.

Support for dict as a cast argument

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?

An option to specify .env filename

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

Cannot set default value for SECURE_PROXY_SSL_HEADER

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).

Quotation Marks on values

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

Empty env variable raises KeyError

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'

Outdated Csv example on the PyPI and in docstring

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.

Config Import Error

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!

(Optionally) Remove settings from environment when reading them

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.

how does it work when deploying on heroku ?

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 ?

Fix the difference between the way python and ipython do recursive searches.

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:

  • settings.ini
  • code.py
  • folder
    • deeper_code.py

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.

decouple get .env file from two parent folders of the project.

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/

Is this project still mantained?

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).

Changelog

The project have a changelog file?

If not, I suggest that create one to facilitate the follow-up of version updates.

How to use decouple with a regular python library?

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.

add changelog and tags for 3.2 and 3.3 releases

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:

  • fixed typos in documentation
  • add editorconfig file
  • fix handling for configuration values that end in single or double quotes (#78)
  • add support for encoding env files in other encodings (#62) (#64)
  • improve csv documentation (#59)

python-decouple 3.3:

  • enforce search order in settings files
  • switch to using strtobool (#71)

Thank you!

AttributeError: 'tuple' object has no attribute 'read'

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'

Dúvida em relação ao arquivo .ini ou .env

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

Environment variables must override .env settings

In the Unix world settings and application parameters are usually evaluated in the following order:

  1. CLI arguments (eg. python -u)
  2. Environment variables (eg. PYTHONUNBUFFERED=1)
  3. Local settings files (eg. ./project/setup.cfg)
  4. User settings files (eg. $HOME/.setup.cfg)
  5. System settings files (eg. /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]

[Feature Request] Port find_dotenv() feature from python-dotenv

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!

Infer cast if default is given

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.

Add yml support.

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.

Deprecated use of readfp

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.