UpstreamDataInc / goosebit

A simplistic, opinionated remote update server implementing hawkBit™'s DDI API.
https://goosebit.rtfd.io
Apache License 2.0
12 stars 2 forks source link

Add support for configuration through env vars #64

Closed easybe closed 4 weeks ago

easybe commented 1 month ago

In addition to the key-value pairs in settings.yaml, the application can now be configured through corresponding GOOSEBIT_* environment variables. E.g. to use PostgreSQL, set:

GOOSEBIT_DB_URI=postgres://db_user:db_pw@postgres:5432/goosebit

The users are configured as follows:

GOOSEBIT_USERS='[{email="foo@b.ar", password="42", permissions="*"}]'

The environment variables have precedence over the configuration file.

For more information, read: https://www.dynaconf.com/envvars/

b-rowan commented 1 month ago

@easybe if you want to merge this go for it, I think this is in a good enough spot for now, and dropping in pydantic later shouldn't be a breaking change, just a matter of when we want to get rid of that extra dependency.

easybe commented 1 month ago

Actually, switching to pydantic might be a breaking change as probably

GOOSEBIT_USERS='[{email="foo@b.ar", password="42", permissions="*"}]'

will no longer work. So, we should probably use it now if we know that it is the path we want to take.

b-rowan commented 1 month ago

Scrolling down a bit, it seems like should still work, we just have an item typed as list[User] or whatever, and it should parse from that.

Copied the example cause there wasn't an anchor nearby...


import os

from pydantic import BaseModel, ValidationError

from pydantic_settings import BaseSettings

class RedisSettings(BaseModel):
    host: str
    port: int

class Settings(BaseSettings, case_sensitive=True):
    redis: RedisSettings

os.environ['redis'] = '{"host": "localhost", "port": 6379}'
print(Settings().model_dump())
#> {'redis': {'host': 'localhost', 'port': 6379}}
os.environ['redis'] = '{"HOST": "localhost", "port": 6379}'  
try:
    Settings()
except ValidationError as e:
    print(e)
    """
    1 validation error for Settings
    redis.host
      Field required [type=missing, input_value={'HOST': 'localhost', 'port': 6379}, input_type=dict]
        For further information visit https://errors.pydantic.dev/2/v/missing
    """
b-rowan commented 1 month ago

I think this shows it accurately enough - https://docs.pydantic.dev/latest/concepts/pydantic_settings/#parsing-environment-variable-values

Quote from docs - "Complex types like list, set, dict, and sub-models are populated from the environment by treating the environment variable's value as a JSON-encoded string."

easybe commented 4 weeks ago

My example uses the TOML format, yours JSON. Note the = vs. :. With dynaconf it would be '@json {"key": "value"}' for JSON.

Anyway, I am all for switching. Just need to find the time.

easybe commented 4 weeks ago

Rendered obsolete by #71