Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use decouple with a regular python library? #22

Closed
fccoelho opened this issue Feb 24, 2016 · 7 comments
Closed

How to use decouple with a regular python library? #22

fccoelho opened this issue Feb 24, 2016 · 7 comments

Comments

@fccoelho
Copy link

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.

@henriquebastos
Copy link
Collaborator

When you from decouple import config you're using the default AutoConfig instance.

It has a magic that searches for the settings.ini file from the caller's module directory. If it can't find there, it keeps searching up the tree.

If you want to have full controle and point directly where your settings.ini is:

from decouple import RepositoryIni, Config
config = Config(RepositoryIni('path/to/settings.ini'))

DEBUG = config('DEBUG')

This API has room for improvement. You're the 2nd to request something like this.

@nielsonsantana
Copy link

I have interest in this feature too. I solve it by override _caller_path

from decouple import AutoConfig

def _caller_path(self):
    return os.getcwd()

AutoConfig._caller_path = _caller_path
config = AutoConfig()

@henriquebastos
Copy link
Collaborator

@nielsonsantana can you provide a patch so we can invert the dependency on the path?

@nielsonsantana
Copy link

I trying figure out how change your code. Are you suggesting to override "_caller_path"?
Replace:

def _caller_path(self):
    # MAGIC! Get the caller's module path.
    frame = sys._getframe()
    path = os.path.dirname(frame.f_back.f_back.f_code.co_filename)
    return path 

for

def _caller_path(self):
    return os.getcwd()

In my tests, it's work based on where it is called from. Per example, if it is called from a terminal, it will use the local .env based on the path of the terminal.

nielsonsantana added a commit to nielsonsantana/python-decouple that referenced this issue Jun 18, 2016
@osantana
Copy link
Contributor

osantana commented Jul 8, 2016

I'd like to make a design suggestion: avoid configuration handling in libraries. The "right place" to handle configuration is your project (that requires/uses the library).

It's better make your library configuration-agnostic, so, the users of your library can use any configuration system. And you can also reduce the number of depedencies.

"Wrong" way

# mylib.py

class Client:
    def __init__(self, url=None):
        self.url = config("URL", default="http://localhost/")
# myproject.py

from mylib import Client

client = Client()

"Right" way

# mylib.py

class Client:
    def __init__(self, url):
        self.url = url
# myproject.py

from mylib import Client

url = config("URL", "http://localhost")
client = Client(url)

@rmax
Copy link
Contributor

rmax commented Aug 6, 2016

I faced this issue when trying to use decouple.config in a jupyter notebook.

This PR #28 allows the users to instantiate AutoConfig with a custom initial search path. For example, in a jupyter notebook:

config = AutoConfig(os.getcwd())

henriquebastos added a commit that referenced this issue Aug 6, 2017
@henriquebastos
Copy link
Collaborator

Fixed tks to @rmax

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants