simplistix / configurator Goto Github PK
View Code? Open in Web Editor NEWA Python library for handling configuration files.
Home Page: https://configurator.readthedocs.io
License: MIT License
A Python library for handling configuration files.
Home Page: https://configurator.readthedocs.io
License: MIT License
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.
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
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
This code:
configurator/configurator/node.py
Lines 110 to 117 in 0e6f539
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])
i have a setup where credentials are loaded from vault into the configuration,
this is done via lazy loading, so that even if there is a full configuration, only the necessary roundtrips are made
if there was a tool to have config nodes load deferred when they are used (not merged) that would be a help
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 ...
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
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)
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.