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

Provide a configuration class #33

Open
hernantz opened this issue Nov 15, 2019 · 5 comments
Open

Provide a configuration class #33

hernantz opened this issue Nov 15, 2019 · 5 comments

Comments

@hernantz
Copy link
Contributor

hernantz commented Nov 15, 2019

Just sharing my thoughts here. This is inspired by GoodConf, and the idea is to allow encapsulating settings inside a structure other than a python module.

from prettyconf import PrettyConf, Value

class AppConfig(PrettyConf):
    "Configuration for My App"
    class Meta:
        loaders = [EnvLoader(), IniFile('/etc/conf.ini/')]
    
    DEBUG = Value(default=False, help="Toggle debugging.")
    DATABASE_URL = Value(
        default='postgres://localhost:5432/mydb',
        help="Database connection.")

Later this object can be used to print settings

>>> conf = AppConfig()
>>> print(conf)
DEBUG=True
DATABASE_URL=postgres://localhost:5432/mydb

Or with __repl__()

>>> conf = AppConfig()
>>> conf
DEBUG=True - Toggle debugging
DATABASE_URL=postgres://localhost:5432/mydb - Database connection.

extended

from base_config import AppConfig

class DevConfig(AppConfig):
    LOG_LEVEL=Value(default='debug')

or passed around

def do_something(cfg):
    if cfg.DEBUG:   # this is evaluated lazily
         return

We would use the existing plumbing to expose this class, which would be another option to use prettyconf.

I don't like that the config('debug') call isn't lazy, so putting it into a class isn't enough:

class MyConfig():
    debug = config('debug')   # this is evaluated when this module is loaded

Printing the current project's config settings is not easy, since there is a lot of garbage in any python module or class.

Any thoughts?

@osantana
Copy link
Owner

Looks promising but I think we need to make a significant refactoring on the current implementation to split the responsibility of:

  1. file configuration discovery
  2. configuration loading
  3. configuration index & reading...

... an do all of it in a 'lazy' way and keeping retro compatibility (and deprecation warnings).

I'm planning to do this refactoring for a long time, but I haven't had time to start the development. I hope I can do it, maybe, at the beginning of 2020.

@osantana
Copy link
Owner

I'm planning to do this refactoring for a long time...

I started this twice and give up on the process because I'm not finding a good way to implement this refactoring and not break backward compatibility :\

@hernantz
Copy link
Contributor Author

Hey @osantana, it wasn't my intention to throw this task at you, but to discuss this idea instead.
I would say it makes more sense for this changes to be tested as a separate package. I'll give it a try.

@osantana
Copy link
Owner

Hey @osantana, it wasn't my intention to throw this task at you, but to discuss this idea instead.
I would say it makes more sense for this changes to be tested as a separate package. I'll give it a try.

Sure! You are helping me a lot with this development.

The main reason why I'm not finding a good approach is not a lack of time but try to get a draft proposal of what I'm planning to do and put here to discuss with you.

The main idea is that I think the "Loaders" are getting more responsibility than they need. I think that we need to split these responsibilities in different objects, but, I also know some projects (that I used to work at) who implement new loaders that would break if I make this split in a not-backward-compatible way.

I will try to make a transparent transition. If I could not do that I will try to make some helpers for this transition (with some deprecation warnings). In the worst scenario, I will just bump the major version and keep two different development streams for some time.

@hernantz
Copy link
Contributor Author

hernantz commented Jun 27, 2020

Hey @osantana,
here is the library I created as a wrapper around prettyconf https://github.com/hernantz/classyconf
I had to move quickly and break backwards compatibility.
This a list of some changes:

  • Implemented reset method for loaders (so that configuration can be reloaded)
  • Boolean cast does not alter the default dict
  • Removed AbstractConfigurationFileLoader
  • Implemented a cache option
  • Added a DictLoader
  • Added the EnvPrefix formatter.

I could backport some of these ideas if you like them, or probably the ones that do not introduce incompatible changes.

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

2 participants