Coder Social home page Coder Social logo

configurator's People

Contributors

cjw296 avatar wimglenn 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

Watchers

 avatar  avatar  avatar  avatar

configurator's Issues

Assignments should strip off any ConfigNode wrappers.

I noticed that Config.__eq__ isn't implemented so we just get object.__eq__ comparison (identity based)

>>> from configurator import Config
>>> c1 = Config({"k": "v"})
>>> c2 = Config({"k": "v"})
>>> c1 == c2
False

Would it be possible to get a content-based equality comparison? In the simple example above we could just use c1.data == c2.data, but my real use-case has a nested configuration so comparing data attributes doesn't work either: the nested values are instances of ConfigNode, which also has identity-based comparison.

My use-case is in testing comparisons, where we want to assert some configs from multiple sources have been parsed and layered the way we expected, without having to recursively extract all the content from the Config instance. i.e., just compare with an "expected" Config or ConfigNode instance directly.

origin of data indication

sometimes when debugging merged configurations, its really helpful to be able to tell what file/line/source an element came from

for example, if a setting can be provided by cli, default settings file and optional settings file it would be a great help to tell

a) where the final setting came from
b) if its a parsed file what line it was

Idea: allow function mappers

Hi, first of all, thanks for this cool project :)

I'm converting the config file from https://github.com/tiangolo/full-stack-fastapi-postgresql/ to use configurator and I'm trying to tidy it up by dividing into different sections.
There are a lot of environment variables loaded in that config, and they mostly follow a pattern, so I was wondering whether it would be helpful to allow for parsing the environment variables as they are loaded. So, for example, run something like this:

def mapper(s: str) -> str:
    header = dict(SMTP='email', POSTGRES='db', ...)
    prefix = s.split("_")[0]
    suffix = "_".join(s.split("_")[1:]
    if prefix in header:
        return f"{header[prefix]}.{suffix.lower()}"
    return s.lower()

config.merge(os.environ, mapper)

This is, of course, just a rough idea rather than a fully functioning example. Optionally if None is returned perhaps the value can be excluded from the merge.

Currently I'm adding all the environment variables I need explicitly to the mapper, but I'm not sure it's ideal.

Cheers,
Omri

ConfigNode.items() should not sort self.data.

This code:

def items(self):
"""
Obtain children of this node by access like :meth:`dict.items`. If the child
is a :class:`dict` or :class:`list`, a :class:`ConfigNode` for it will
be returned, otherwise the value itself will be returned.
"""
for key, value in sorted(self.data.items()):
yield key, self._wrap(key, value)

...should not sort, as the ordering in the underlying dict map have important meaning!

loading a specific "path" of a config file and/or loading multiple of them

i have a setup where we are using dynaconf style environment

which means that instead of

myconfig:
   host: abc
   port: 1337

we have something like

# settings.yaml
default:
  myconfig:
     port: 1337
prod:
  myconfig:
    host: danger.example.com
qe:
  myconfig:
     host: qe.hidden.example.com

then the full config ought to be created via something like

# first rough draft, please destroy :)
def load_config(current_env="qe"):
   setting = Config.from_path("settings.yaml")
   local = Config.from_path("setting.local.yaml", optional=True)
   return merge_from_environments(configs=[settings, local], environments=["global", "default", current_env])

Make it easier to plug in different parsers for file types.

Currently you can either use the built-in ones or provide a callable for each parser call.
This is an issue if, say, you want to plug in a different yaml parser for all yaml usage, particularly when configurator is used within an application or library whose source code you don't want to modify.

This also came up on #7 ...

case insensitive loading/lookup as opt-in

when migrating from other configuration systems, those sometimes are very lenient on how they deal with uppercase/lowercase/mixed case keys

it would be nice to be able to

  1. normalize the case of keys on loading + warning when normalization was necessary
  2. normalize the case of lookup when using config objects in old code

example:

# settings.yaml
MAIN:
  hostname: deathstar.example.com
# load_config.py

config = Config.from_path("settings.yaml")
fixed_config = Config()
fixed_config.merge(config, context=CaseNormalizer(normalize=str.lower, warn=True)
# warns here about MAIN needing to be renamed to main

safely_usable_config = CaseSensitiveLookup(fixed_config)
def get_host(settings):
   # legacy code, gets warning about MAIN and HOST
   return settings.MAIN.HOST
  
get_host(safely_usable_config)

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.