How to implement configuration shared by different modules?

Hi,

Let’s say that I have a project with multiple modules. Each of them requires certain configuration. What is the recommended way to store that config file and make it available to the whole project?

I would make a config module (or something like it) and import it in each module. The config module itself doesn’t import anything from your project, to avoid circular dependencies.

I’ll also make a distinction between “config” and constants, if you have both: I like config in a text file (yaml or similar) and be loaded when the project starts. The project can include a template file with defaults and users can provide their own if desired–this allows people to change config without editing code. You might write a Config class that loads this file and then pass this object to functions/classes.

constants, on the other hand, are a way to avoid “magic numbers” in your code and store all the values you use in a single place. It can be a separate file that is imported as needed. This is stuff that isn’t configurable by users, but makes development cleaner and easier to read.

2 Likes

Hello James,

Thanks for your answer. Is there a recommended config class that we can use to load the config file? Or do you think it is better that we implement it ourselves? Also is there a recommended format for the config file? Like TOML, JSON, etc.

There are many recommendations! :joy: No one is in charge of this stuff.

I like YAML because it’s easy to read and write. TOML and JSON have the advantage of stdlib support (as of 3.11 in the case of TOML).

I would implement your own Config class because the idea is to encode the things you care about in a way that your IDE etc can analyze–a generic version won’t know that my_config.default_directory is a thing, but you can define that as a class attribute or property. But it doesn’t need to be complicated.

1 Like

JSON has the disadvantage of not (in its official form) supporting comments – and it’s not quite as human writable as YAML or TOML. Which points to TOML.

INI is another (stdlib) option (import configparser), but pretty dated these days.

Using a dataclass is a great way to get config class that’s very easy to write.

2 Likes

True! A dataclass is a great place to start. I often add a static load_config method or something similar, so the code for loading the file is attached to the class.

A key thing to watch out for with this pattern is that you want to load that config once at the beginning of your program. That means being careful about tracking all the entry points.

I tend to already have a yaml dependency somewhere so the lack of stdlib support isn’t a big issue for me.