simpleconf
Simple configuration management for python
Installation
# released version
pip install python-simpleconf
# Install support for ini
pip install python-simpleconf[ini]
# Install support for dotenv
pip install python-simpleconf[dotenv]
# Install support for yaml
pip install python-simpleconf[yaml]
# Install support for toml
pip install python-simpleconf[toml]
# Install support for all supported formats
pip install python-simpleconf[all]
Features
- Multiple formats supported
- Type casting
- Profile support
- Simple APIs
- Async loading support
- Templated configuration files support (jinja2 and liquid)
Usage
Loading configurations
import asyncio
from simpleconf import Config
async def main():
# Load a single file
conf = Config.load('~/xxx.ini')
# load multiple files, later files override previous ones
conf = Config.load(
'~/xxx.ini', '~/xxx.env', '~/xxx.yaml', '~/xxx.toml',
'~/xxx.json', 'simpleconf.osenv', {'a': 3}
)
# Load a single file with a different loader
conf = Config.load('~/xxx.ini', loader="toml")
# Async loading
conf = await Config.a_load('~/xxx.ini')
if __name__ == "__main__":
asyncio.run(main())
Accessing configuration values
from simpleconf import Config
conf = Config.load({'a': 1, 'b': {'c': 2}})
# conf.a == 1
# conf.b.c == 2
Supported formats
.ini/.cfg/.config(parsed byiniconfig).- For confiurations without profiles, an ini-like configuration like must have a
default(case-insensitive) section.
- For confiurations without profiles, an ini-like configuration like must have a
.env(usingpython-dotenv). A file with environment variables..yaml/.yml(usingpyyaml). A file with YAML data..toml(usingrtoml). A file with TOML data..json(usingjson). A file with JSON data.XXX.osenv: System environment variables with prefixXXX_(case-sensitive) is used.XXX_A=1will be loaded asconf.A = 1.
- python dictionary.
- Strings format of the above formats are also supported.
"{'a': 1}"will be loaded asconf.a = 1.
Profile support
Loading configurations
Loading dictionaries
from simpleconf import ProfileConfig
conf = ProfileConfig.load({'default': {'a': 1})
# conf.a == 1
# Asynchronous loading
# conf = await ProfileConfig.a_load({'default': {'a': 1})
# conf.a == 1
Loading a .env file
config.env
# config.env
default_a=1
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.env')
# conf.a == 1
Loading ini-like configuration files
# config.ini
[default]
a = 1
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.ini')
# conf.a == 1
Loading JSON files
config.json
{
"default": {
"a": 1
}
}
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.json')
# conf.a == 1
Loading system environment variables
from os import environ
from simpleconf import ProfileConfig
environ['XXX_DEFAULT_A'] = '1'
conf = ProfileConfig.load('XXX.osenv')
# conf.a == 1
Loading TOML files
# config.toml
[default]
a = 1
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.toml')
# conf.a == 1
Loading YAML files
# config.yaml
default:
a: 1
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.yaml')
# conf.a == 1
Switching profile
from simpleconf import ProfileConfig
conf = ProfileConfig.load(
{'default': {'a': 1, 'b': 2}, 'dev': {'a': 3}, 'prod': {'a': 4}}
)
# conf.a == 1; conf.b == 2
# ProfileConfig.profiles(conf) == ['default', 'dev', 'prod']
# ProfileConfig.pool(conf) == {'default': {'a': 1, 'b': 2}, 'dev': {'a': 3}, 'prod': {'a': 4}}
# ProfileConfig.current_profile(conf) == 'default'
# ProfileConfig.base_profile(conf) == 'default'
ProfileConfig.use_profile(conf, 'dev')
# conf.a == 3; conf.b == 2
# ProfileConfig.current_profile(conf) == 'dev'
# ProfileConfig.base_profile(conf) == 'default'
# use a different base profile
ProfileConfig.use_profile(conf, 'prod', base='dev')
# conf.a == 4 # No 'b' in conf
# ProfileConfig.current_profile(conf) == 'prod'
# ProfileConfig.base_profile(conf) == 'dev'
# Copy configuration instead of inplace modification
conf2 = ProfileConfig.use_profile(conf, 'dev', copy=True)
# conf2 is not conf
# conf2.a == 3; conf2.b == 2
# Use a context manager
with ProfileConfig.use_profile(conf2, 'default'):
conf2.a == 3
conf2.b == 2
# conf2.a == 3; conf2.b == 2
Type casting
For configuration formats with type support, including dictionary, no type casting is done by this library, except that for TOML files.
TOML does not support None value in python. We use rtoml library to parse TOML files, which dumps None as "null". So a null_caster is used to cast "null" to None.
A none_caster is also enabled for TOML files, a pure string of "@none" is casted to None.
For other formats, following casters are supported:
Int caster
from os import environ
from simpleconf import Config
environ['XXX_A'] = '@int:1'
conf = Config.load('XXX.osenv')
# conf.a == 1 # int
Float caster
@float:1.0 -> 1.0
Bool caster
@bool:true -> True
@bool:false -> False
Python caster
Values are casted by ast.literal_eval().
"@python:1" => 1 # or
"@py:1" => 1
"@py:1.0` -> `1.0`
"@py:[1, 2, 3]" => [1, 2, 3]
JSON caster
@json:{"a": 1} -> {"a": 1}
TOML caster
@toml:a = 1 -> {"a": 1}
Templated configuration files
jinja2 and liquid templating engines are supported. The templating engine is determined by the file extension, which can be either the primary or secondary suffix. For example, config.toml.j2 and config.j2.toml are both treated as TOML files with Jinja2 templating.
config.toml.j2
a = {{ 1 + 2 }}
from simpleconf import Config
conf = Config.load('config.toml.j2')
# conf.a == 3
config.liq.toml
{% for i in range(1, 3) %}
[section{{i}}]
a = {{i}}
{% endfor %}
from simpleconf import Config
conf = Config.load('config.liq.toml')
# conf.section1.a == 1
# conf.section2.a == 2
Loader directive
Instead of using a special file extension, you can embed a loader directive in the first lines of a configuration file as a comment. This allows a plain config.toml to be processed by the Liquid engine without renaming the file.
The directive format is:
# simpleconf-loader: <loader>
Supported comment prefixes: #, ;, // (case-insensitive).
The <loader> value can be:
| Value | Meaning |
|---|---|
liq or liquid |
Use the Liquid loader for this file's format |
j2, jinja, or jinja2 |
Use the Jinja2 loader for this file's format |
A full extension (e.g. toml.liq) |
Use the exact loader specified |
Example — Liquid in a plain .toml file:
config.toml
# simpleconf-loader: liq
{% set x = 10 %}
[default]
a = {{ 1 + 1 }}
b = {{ x + 2 }}
from simpleconf import Config
conf = Config.load('config.toml')
# conf.default.a == 2
# conf.default.b == 12
Example — Jinja2 in a plain .yaml file:
config.yaml
# simpleconf-loader: j2
default:
a: {{ 1 + 1 }}
from simpleconf import Config
conf = Config.load('config.yaml')
# conf.default.a == 2
Loadenv directive
You will need python-dotenv installed to use the loadenv directive. You can install it with:
pip install python-simpleconf[toml,env]
if you only need TOML and dotenv support, or
pip install python-simpleconf[all]
if you want all supported formats.
You can also embed a # simpleconf-loadenv directive in the first few lines of a configuration file to load environment variables from a .env file. This allows you to reference environment variables directly in your config values using $env:VAR syntax, and makes them available as env in Jinja2/Liquid templates via {{ env.VAR }} or {{ env["VAR"] }}.
The directive format is:
# simpleconf-loadenv
# simpleconf-loadenv: /path/to/.env
When no path is given, ./.env is loaded (relative to the config file's directory).
Supported comment prefixes: #, ;, // (case-insensitive).
Example — using $env:VAR references:
.env
DB_HOST=localhost
DB_PORT=@int:5432
config.yaml
# simpleconf-loadenv
db:
host: $env:DB_HOST
port: $env:DB_PORT
from simpleconf import Config
conf = Config.load('config.yaml')
# conf.db.host == 'localhost'
# conf.db.port == 5432 # @int: cast to int
The $env:VAR syntax works in all supported formats (YAML, TOML, INI, JSON, .env). In formats that require quoted strings (TOML), wrap the reference in quotes: "$env:DB_HOST".
Lookup order: the loaded .env file is checked first, then os.environ as a fallback.
Modifiers — controlling what happens when a variable is not found
The $env: syntax supports optional modifiers to control the behavior when a variable is not found:
| Syntax | Behavior when VAR not found |
|---|---|
$env:VAR |
Default — raises ValueError |
$env:VAR:required |
Explicit form — raises ValueError |
$env:VAR:optional-asis |
Keeps the literal $env:VAR string unchanged |
$env:VAR:optional-empty |
Resolves to an empty string "" |
Example — using modifiers:
.env
DB_HOST=localhost
config.yaml
# simpleconf-loadenv
db:
host: $env:DB_HOST
port: $env:DB_PORT:optional-asis # keeps "$env:DB_PORT" as-is when not found
timeout: $env:TIMEOUT:optional-empty # becomes "" when not found
from simpleconf import Config
conf = Config.load('config.yaml')
# conf.db.host == 'localhost'
# conf.db.port == '$env:DB_PORT'
# conf.db.timeout == ''
Example — using env in templates:
.env
DB_HOST=localhost
DB_PORT=5432
config.toml
# simpleconf-loadenv
# simpleconf-loader: liq
[default]
url = "{{ env.DB_HOST }}:{{ env.DB_PORT }}"
from simpleconf import Config
conf = Config.load('config.toml')
# conf.default.url == 'localhost:5432'
Both directives (simpleconf-loader and simpleconf-loadenv) can coexist in the same file on different lines. The order does not matter.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file python_simpleconf-0.9.5.tar.gz.
File metadata
- Download URL: python_simpleconf-0.9.5.tar.gz
- Upload date:
- Size: 230.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ad16937a8744aaf6456bea65b33c1340fa6f06c22b6174cc1b98a05482ab37a
|
|
| MD5 |
383fa1db7c2d71d535c23d08e739d308
|
|
| BLAKE2b-256 |
f7f5ccfb4a2c1e0bf82496a32df7b51f1ce8d9098f7c3c194b8681489fd1f2cd
|
File details
Details for the file python_simpleconf-0.9.5-py3-none-any.whl.
File metadata
- Download URL: python_simpleconf-0.9.5-py3-none-any.whl
- Upload date:
- Size: 20.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9734b549e18f9b58a181749891d2b3c3a6186979aada8d7911259a42dc8710b4
|
|
| MD5 |
098d628a43b5c3a3b206d80c713d6039
|
|
| BLAKE2b-256 |
1a92c3dfb1510cec188ccf5387724641b38fcac457167c2c3f43ea0bb7cf1ccb
|