gConfigs - Configuration helper for Python applications.
Project description
gConfigs
Configuration helper for Python applications.
gConfigs provides a unified API to read configuration values from different sources:
- Environment variables
- Dotenv files
- INI files
- TOML files
- Local mounted files in a directory
- Individual local files
Why another config library?
I made it for myself. That's it.
Installation
Python 3.11+
pip install gconfigs
or with uv:
uv add gconfigs
Or even better. It's small enough, avoid the dependency entirely, and copy gconfigs/ into your project.
Extra effort to convince you to avoid dependencies: maybe all you need is just os.environ.
Quick Start
import gconfigs
# 1) Environment variables
envs = gconfigs.envs()
debug = envs("DEBUG", default=False, cast=bool)
home = envs("HOME", default="/")
# 2) Mounted directory (for configs or secrets)
configs = gconfigs.local_files("/run/configs")
language_code = configs("LANGUAGE_CODE", default="en-us")
# 3) Single local file
secrets = gconfigs.local_file()
db_password = secrets("/run/secrets/DB_PASSWORD")
# 4) Dotenv file
dotenvs = gconfigs.dotenvs(".env")
project_name = dotenvs("PROJECT_NAME", default="my-app")
# 5) INI file
ini = gconfigs.ini_file("./config/settings.ini")
app_name = ini("app.name", default="my-app")
# 6) TOML file
toml = gconfigs.toml_file("./config/settings.toml")
db_port = toml("database.port", cast=int)
API Overview
The package exposes six factory functions:
- gconfigs.envs() -> reads from process environment variables
- gconfigs.dotenvs(filepath=".env") -> reads from dotenv files
- gconfigs.ini_file(filepath=".ini") -> reads from INI files using section.option keys
- gconfigs.toml_file(filepath=".toml") -> reads from TOML files using dotted keys
- gconfigs.local_files(path="/run/configs", pattern="*") -> reads from files in a directory
- gconfigs.local_file() -> reads from a single file path provided at call time
Each factory returns a GConfigs instance.
Main call signature:
GConfigs.get(key, *, default=NOTSET, use_instead=NOTSET, strip=None, cast=None, list_sep=None, bool_values=None, **backend_kwargs)
Usage
Environment Variables
import gconfigs
envs = gconfigs.envs()
home = envs("HOME")
workers = envs("WORKERS", default="2", cast=int)
debug = envs("DEBUG", default=False, cast=bool)
Dotenv Files
import gconfigs
dotenvs = gconfigs.dotenvs("./config/.env")
dsn = dotenvs("DATABASE_DSN")
# load another dotenv file with a different GConfigs instance
other = gconfigs.dotenvs("./config/another.env")
INI Files
import gconfigs
ini = gconfigs.ini_file("./config/settings.ini")
app_name = ini("app.name")
db_host = ini("database.host")
db_port = ini("database.port", cast=int)
INI parser behavior:
- Keys use section.option format
- Values are read as strings by default
- Use cast to convert values
- Missing section/option raises KeyError
TOML Files
import gconfigs
toml = gconfigs.toml_file("./config/settings.toml")
app_name = toml("name")
db_host = toml("database.host")
db_port = toml("database.port", cast=int)
pool_size = toml("database.pool.size", cast=int)
TOML parser behavior:
- Keys use dotted access for nested tables
- Values preserve native TOML types (e.g. int, bool, list)
- Missing nested keys raise KeyError
Dotenv parser behavior:
- Ignores lines starting with #, ;, and [section]
- Ignores lines without =
- Splits at the first = so values can contain =
- Strips key whitespace
- Preserves value whitespace (except trailing newline characters)
- Last duplicated key wins
Local Mounted Files (Directory)
import gconfigs
configs = gconfigs.local_files("/run/configs")
secrets = gconfigs.local_files("/run/secrets")
api_url = configs("API_URL")
api_key = secrets("API_KEY")
How it works:
- Relative file path is the config key
- File content is the config value
- Optional pattern argument filters which files are considered
- Keys are file names directly inside the configured base path
- Reads are restricted to the configured base path (path traversal like
../secretis blocked) - Recursive access is intentionally not supported (nested paths like
nested/key.txtare rejected)
only_app = gconfigs.local_files("/run/configs", pattern="APP_*")
* Uses fnmatch for pattern matching. fnmatch docs
Single Local File
import gconfigs
secrets = gconfigs.local_file()
token = secrets("/run/secrets/SERVICE_TOKEN")
Common Patterns
Default Value
port = envs("PORT", default="8000")
Fallback Key with use_instead
host = envs("SERVICE_HOST", use_instead="HOST", default="127.0.0.1")
Strip Control
By default, returned string values are stripped.
value = envs("MY_KEY") # strip=True by default
raw_value = envs("MY_KEY", strip=False)
Type Casting
Use cast in GConfigs.get (or by calling the instance directly) to convert values.
Boolean
- Accepts native bool values
- Accepts case-insensitive string pairs from bool_values
- Default bool_values pairs:
- ("true", "false")
- ("1", "0")
- ("yes", "no")
- ("y", "n")
- ("on", "off")
debug = envs("DEBUG", default=False, cast=bool)
feature_enabled = envs(
"FEATURE_X",
cast=bool,
bool_values=(("enabled", "disabled"),),
)
list, tuple, and set
- Accepts native iterable values for conversion between list/tuple/set
- Accepts JSON-style list strings like "[1, 2, 3]"
- Accepts separator-delimited strings using list_sep
hosts = envs("ALLOWED_HOSTS", cast=list)
hosts_csv = envs("ALLOWED_HOSTS_CSV", cast=list, list_sep=",")
hosts_pipe = envs("ALLOWED_HOSTS_PIPE", cast=list, list_sep="|")
coords = envs("COORDS", cast=tuple)
labels = envs("LABELS", cast=set)
dict
- Accepts native dict values
- Accepts JSON-style object strings like "{"workers": 2}"
options = envs("APP_OPTIONS", cast=dict)
Custom cast function or type
from decimal import Decimal
price = envs("PRICE", cast=Decimal)
def normalize_slug(value):
return str(value).strip().lower().replace(" ", "-")
slug = envs("PROJECT_NAME", cast=normalize_slug)
Output Formatting with ValueOutput
GConfigs delegates output conversion and strip behavior to ValueOutput.
Default behavior:
- strip=True
- list_sep=","
- bool_values as described in the casting section
You can pass a custom ValueOutput instance to GConfigs:
from gconfigs.gconfigs import GConfigs, ValueOutput
class DictBackend:
def __init__(self):
self.data = {"DEBUG": "enabled", "HOSTS": "a|b|c"}
def keys(self):
return self.data.keys()
def get(self, key, **backend_kwargs):
if key not in self.data:
raise KeyError(f"{key} not set")
return self.data[key]
output_fmt = ValueOutput(list_sep="|", bool_values=(("enabled", "disabled"),))
configs = GConfigs(backend=DictBackend, output_fmt=output_fmt)
debug = configs("DEBUG", cast=bool)
hosts = configs("HOSTS", cast=list)
Iteration and Utilities
GConfigs implements container and iterator protocols.
import gconfigs
envs = gconfigs.envs()
if "HOME" in envs:
print("HOME exists")
print(len(envs))
for item in envs:
print(item.key, item.value)
print(envs.json())
Notes:
- Iteration yields namedtuples with key and value fields
- Use .iterator() when you need a fresh independent iterator
Error Behavior
Typical exceptions you may see:
- KeyError for missing environment variable or missing dotenv key
- FileNotFoundError for missing paths/files in file backends
- PermissionError for unreadable files in local_file backend
- ValueError for invalid cast values
Use default=... to avoid exceptions for missing keys when appropriate.
Custom Backend
You can plug your own backend into GConfigs.
Required backend methods:
- get(key: str, **backend_kwargs)
- keys()
Example:
from gconfigs.gconfigs import GConfigs
class DictBackend:
def __init__(self):
self.data = {"NAME": "my-app", "DEBUG": "false"}
def additional_method(self):
return "This is an additional method in the backend class."
def keys(self):
return self.data.keys()
def get(self, key, **backend_kwargs):
if key not in self.data:
raise KeyError(f"{key} not set")
return self.data[key]
configs = GConfigs(backend=DictBackend)
name = configs("NAME")
debug = configs("DEBUG", cast=bool)
# You can access the backend instance directly from GConfigs instance
assert configs.backend.additional_method
License
MIT. See LICENSE-MIT.
Project details
Release history Release notifications | RSS feed
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 gconfigs-2.0.0.tar.gz.
File metadata
- Download URL: gconfigs-2.0.0.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75706094120d0e2f462e3ed59ed4b7a57f8b0b71d03f8995a88e57123be61a75
|
|
| MD5 |
aeb52f15505a05fb05f9c399a5a9cedb
|
|
| BLAKE2b-256 |
6ebc6d37d42c3b130aa1d18650bb51c538deb78fc49b46f1a8200c4f262bc500
|
Provenance
The following attestation bundles were made for gconfigs-2.0.0.tar.gz:
Publisher:
publish.yaml on douglasmiranda/gconfigs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gconfigs-2.0.0.tar.gz -
Subject digest:
75706094120d0e2f462e3ed59ed4b7a57f8b0b71d03f8995a88e57123be61a75 - Sigstore transparency entry: 1436901081
- Sigstore integration time:
-
Permalink:
douglasmiranda/gconfigs@2dfe005457afd907387aa28493590dffa057c68c -
Branch / Tag:
refs/tags/2.0.0 - Owner: https://github.com/douglasmiranda
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@2dfe005457afd907387aa28493590dffa057c68c -
Trigger Event:
release
-
Statement type:
File details
Details for the file gconfigs-2.0.0-py3-none-any.whl.
File metadata
- Download URL: gconfigs-2.0.0-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f48b98b33336c1af0e6cd3294bc007424a63e9d5fd3e4958aa2ce46dbb814e9c
|
|
| MD5 |
a0c449e2b286e87e20576cf2ea487d76
|
|
| BLAKE2b-256 |
2bd5548764c429e70ecbb347d6bb8c9960cebc68d8197e214700e2f5323ba6db
|
Provenance
The following attestation bundles were made for gconfigs-2.0.0-py3-none-any.whl:
Publisher:
publish.yaml on douglasmiranda/gconfigs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gconfigs-2.0.0-py3-none-any.whl -
Subject digest:
f48b98b33336c1af0e6cd3294bc007424a63e9d5fd3e4958aa2ce46dbb814e9c - Sigstore transparency entry: 1436901083
- Sigstore integration time:
-
Permalink:
douglasmiranda/gconfigs@2dfe005457afd907387aa28493590dffa057c68c -
Branch / Tag:
refs/tags/2.0.0 - Owner: https://github.com/douglasmiranda
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@2dfe005457afd907387aa28493590dffa057c68c -
Trigger Event:
release
-
Statement type: