Skip to content

Options pattern #582

Open
Open
@panicoenlaxbox

Description

@panicoenlaxbox

Hello,

I'm a happy user of your package, it's awesome. I come from the .NET stack and find it very useful in Python.

I don't know if it is available or not in the package, but I miss a couple of things that I used a lot in .NET applications.

The first one is the possibility of loading configuration from a .json file. I know that I can use .ini, .yaml, and other formats, but I think it would be good to support .json also.

The second one, and the most important in my opinion, is don't have something similar to this out-of-the-box https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-6.0

The idea behind this, it's to allow to inject "part" of the configuration like an object. For now, I'm using a workaround that works perfectly.

config.json

{
  "foo": {
    "bar": "bar",
    "baz": "baz"
  },
  "qux": "qux"
}

foo_options.py

from dataclasses import dataclass


@dataclass
class FooOptions:
    bar: str
    baz: str

containers.py

import json

from dacite import from_dict
from dependency_injector.containers import DeclarativeContainer, WiringConfiguration
from dependency_injector import providers

from foo_options import FooOptions


def _create_foo_options() -> FooOptions:
    with open("config.json") as f:
        return from_dict(FooOptions, json.loads(f.read())["foo"])  # using dacite package https://github.com/konradhalas/dacite


class Container(DeclarativeContainer):
    wiring_config = WiringConfiguration(
        modules=["__main__"]
    )

    foo_options = providers.Singleton(_create_foo_options)

main.py

from dependency_injector.wiring import inject, Provide

from containers import Container
from foo_options import FooOptions


@inject
def main(foo_options: FooOptions = Provide[Container.foo_options]):
    print(foo_options)  # FooOptions(bar='bar', baz='baz')


if __name__ == '__main__':
    container = Container()
    main()

I would like to know your opinion about this. What I want to avoid is having a big object with all my configuration when a class only needs to be aware of a little part. I know that I can inject concrete values of config using Configuration provider or even the whole config like a dict, but I want to use dataclasses with types safety and don't use primitive values.

Congrats for your great job, I couldn't live without this package :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions