django-extra-settings icon indicating copy to clipboard operation
django-extra-settings copied to clipboard

Environment layer

Open InzGIBA opened this issue 2 years ago • 6 comments

I think the suggestion to add a new data layer has a place.

Case: When initializing a project, you can specify certain parameters in CI/CD and then override them in the database.

Code (link):

# shortcut
@staticmethod
def _get_from_env(name):
    return environ.get(name, None)

# updated method
@classmethod
def get(cls, name, default=None):
    val = cls._get_from_cache(name)
    if val is None:
        val = cls._get_from_database(name)
        if val is None:
            val = cls._get_from_env(name)
            if val is None:
                val = cls._get_from_settings(name)
                if val is None:
                    val = default
    return val
Fund with Polar

InzGIBA avatar Jun 01 '22 06:06 InzGIBA

It would also be interesting to have a solution to switch the priorities of the data sources.

A possible solution is to create a map, in the form of a dictionary that matches keys and functions (values) and cycles to the first find.

Examples:

  1. cache
  2. database
  3. env
  4. settings

  1. cache
  2. database
  3. settings
  4. env

etc...

InzGIBA avatar Jun 01 '22 06:06 InzGIBA

@InzGIBA

  • I agree with the possibility to define layers priority
  • Reading from env variables could give some problems with types because all values would be strings, any idea?!

fabiocaccamo avatar Jun 02 '22 17:06 fabiocaccamo

There is a thought of splitting the model into several abstract models. Where in each one there will be a check depending on the type of value.

  • If the variable type is "string", try converting in "_get_from_env"

Depending on external rule in settings, output traceback

InzGIBA avatar Jun 03 '22 19:06 InzGIBA

If you are interested in the idea, I can implement it in fork and send it to you for review

InzGIBA avatar Jun 03 '22 19:06 InzGIBA

@InzGIBA I'm not convinced about this approach, I would like to keep it very simple as it is now, I will think about this...

fabiocaccamo avatar Jun 06 '22 07:06 fabiocaccamo

How about integrating with the "EXTRA_SETTINGS_DEFAULTS" variable, where "value" is optional or will it be taken depending on the priority?

  • from cache
  • from database
  • from env
  • from default

But in the layer "env" there will be a check, if there is "env" and a value with the same "name" it will be checked, otherwise this layer will be skipped.

In the same way we can add a variable "EXTRA_SETTINGS_ENV_EXCEPT" - if the type conversion failed, it will raise Exception, otherwise this value will be skipped.

InzGIBA avatar Mar 20 '23 12:03 InzGIBA

@InzGIBA I changed my mind about this issue.

  • Adding the possibility to change layers ordering would open the doors to many potential new issues when actually the current implementation covers the most part of the use cases, so I think that the effort is not repaid.

  • Reading settings from env variables implies more work than expected because they are not typed, so I would suggest you to read env vars using django-environ so this package can access them as normal django settings.

fabiocaccamo avatar Mar 05 '24 09:03 fabiocaccamo