
Security News
Vite Releases Technical Preview of Rolldown-Vite, a Rust-Based Bundler
Vite releases Rolldown-Vite, a Rust-based bundler preview offering faster builds and lower memory usage as a drop-in replacement for Vite.
A robust, schema-driven configuration management library for Python with encryption, versioning, nested sections, and multiple backends.
Stop fighting inconsistent, error-prone, and insecure configuration files! š
ConfigGuard transforms your Python application's configuration management from a potential source of bugs and security risks into a robust, reliable, and developer-friendly system. Moving beyond simple dictionaries or basic file parsing, ConfigGuard introduces a schema-driven fortress for your settings, offering unparalleled control and safety.
Leverage a comprehensive suite of features designed for modern applications:
min
, max
, options
, nullable
).__version__
key) and automated Migration (with optional automatic file updates).Why waste time debugging subtle configuration typos or managing insecure secrets manually? ConfigGuard catches errors early, simplifies maintenance, and secures your sensitive data, allowing you to focus on building great features.
Adopt ConfigGuard and configure with confidence!
__version__
key for robust version tracking, or override with the instance_version
parameter during initialization."type": "section"
). Access nested settings intuitively through standard attribute or dictionary notation (e.g., config.database.connection.pool_size
, config['server']['ssl']['enabled']
)."schema": {}
) to allow adding/removing arbitrary key-value pairs at runtime, bypassing schema validation for those items while still benefiting from saving, loading, and encryption.cryptography
). Encryption is handled automatically by the storage backend during save/load operations."1.2.0"
) using the standard __version__
key or provide it via instance_version
. ConfigGuard compares file version with instance version during load()
, preventing loading of newer configurations and migrating older ones (merging existing values, applying new defaults, skipping removed items). Migration operates recursively through nested sections. Optionally auto-save the migrated configuration back to the file using load(update_file=True)
.__version__
: Holds the configuration version. Included in both values
and full
save modes.__schema__
: Holds the schema definition. Included only in mode='full'
saves and exports.__settings__
: Holds the configuration values structure. Included only in mode='full'
saves and exports.mode='values'
(default): Saves only the current configuration key-value pairs, prepended with the __version__
key.mode='full'
: Saves the complete state using standard keys: __version__
, __schema__
, and __settings__
.str
, int
, float
, bool
, list
. Dynamic sections can store any JSON-serializable type.config.section.setting
) or dictionary (config['section']['setting']
) syntax. Retrieve schema details using config.sc_section.sc_setting
. Use section.get_schema_dict()
and section.get_config_dict()
for section introspection.export_schema_with_values()
: Get a snapshot using standard keys (__version__
, __schema__
, __settings__
).import_config(data, ignore_unknown=True)
: Update values from a dictionary, merging data, validating standard settings, and adding/updating dynamic keys. Ignores __version__
key in input data
.StorageHandler
classes for additional backends.(Reasons remain largely the same, but updated phrasing for versioning/keys)
__version__
) allows confident schema updates. Migration handles older files, and load(update_file=True)
can automatically bring them up-to-date.__version__
, __schema__
, __settings__
) provide predictable structure.(Installation instructions remain the same)
# Base
pip install configguard
# Extras (encryption, yaml, toml, all, dev)
pip install configguard[encryption]
pip install configguard[yaml]
pip install configguard[toml]
pip install configguard[all]
# For development
git clone https://github.com/ParisNeo/ConfigGuard.git
cd ConfigGuard
pip install -e .[dev]
from configguard import ConfigGuard, ValidationError, generate_encryption_key
from pathlib import Path
import typing
# 1. Define schema with standard __version__ key
SCHEMA_VERSION = "1.1.0"
my_schema: typing.Dict[str, typing.Any] = {
"__version__": SCHEMA_VERSION,
# ... (rest of schema definition as before) ...
"server": {
"type": "section", "help": "Core web server settings.",
"schema": {
"host": { "type": "str", "default": "127.0.0.1", "help": "IP address to bind to." },
"port": { "type": "int", "default": 8080, "min_val": 1024, "max_val": 65535, "help": "Port number." }
}
},
"plugin_data": { "type": "section", "schema": {}, "help": "Dynamic data."}, # Dynamic
"log_level": { "type": "str", "default": "INFO", "options": [...], "help": "Verbosity."}
}
# 2. Setup
config_file = Path("my_app_config.yaml")
encryption_key = generate_encryption_key()
# 3. Initialize (using schema version in this case)
try:
config = ConfigGuard(
schema=my_schema,
config_path=config_file,
encryption_key=encryption_key
)
print(f"Initialized with Version: {config.version}") # -> 1.1.0
# Handle missing dependencies
except ImportError as e: print(f"ERROR: Missing dependency for {config_file.suffix}: {e}"); exit()
except Exception as e: print(f"ERROR: Failed to initialize: {e}"); exit()
# 4. Access defaults
print(f"Initial Host: {config.server.host}") # -> '127.0.0.1'
# 5. Modify values
config.server.port = 9090
config.plugin_data['active'] = True # Dynamic add
# 6. Save configuration (values mode)
# This will save {'__version__': '1.1.0', 'server': {'host': ..., 'port': 9090}, ...}
config.save()
print(f"Config saved to {config_file} (encrypted, with version key).")
# To save full state (version, schema, settings) using standard keys:
# config.save(mode='full', filepath='my_app_config_full.yaml')
# 7. Load older version and auto-update file (Example)
# Assume 'old_config_v1.yaml' exists (saved with version 1.0.0)
# try:
# print("\nLoading old config with auto-update...")
# # Load V1 data into V1.1.0 instance, triggering migration and save
# config_migrated = ConfigGuard(
# schema=my_schema, # V1.1.0 schema
# config_path="old_config_v1.yaml",
# load_options={'update_file': True} # <--- Enable auto-save on migrate
# )
# # Now 'old_config_v1.yaml' should contain migrated data with '__version__': '1.1.0'
# print(f"Loaded and potentially updated file. New instance version: {config_migrated.version}")
# except Exception as e:
# print(f"Error during migration load: {e}")
__version__
key in schema or instance_version
parameter (priority). Standard packaging
format. Defaults to "0.0.0"
.__version__
, __schema__
, __settings__
used for save/export structure."type": "section"
, "schema": {}
).get_schema_dict()
/get_config_dict()
.values
vs full
):
mode='values'
: Saves __version__
+ config values structure.mode='full'
: Saves __version__
, __schema__
, __settings__
.__version__
. Migrates older files. load(update_file=True)
saves migrated state back to file in values
mode.(Use __version__
standard key)
# Example schema definition (use __version__)
schema_v3 = {
"__version__": "3.0.0",
# ... rest of complex_schema definition ...
}
(Pass schema, path, key, optional instance_version
, load_options
)
# Example init with auto-update on migration enabled
config = ConfigGuard(
schema=schema_v3,
config_path="app_v3.db",
encryption_key=enc_key,
load_options={'update_file': True} # Enable save on migrate
)
(Remains the same: config.section.setting
, config['section']['setting']
, config.sc_section.sc_setting
)
(Remains the same: attribute/item assignment triggers validation)
(Remains the same: section.get_schema_dict()
, section.get_config_dict()
)
save()
uses standard keys based on mode
. load()
detects standard/legacy keys and structure. load(update_file=True)
triggers save after migration.
# Save values (includes __version__)
config.save() # or config.save(mode='values')
# Save full state (__version__, __schema__, __settings__)
config.save(mode='full', filepath='backup.json')
# Load (will check standard keys first)
try:
config.load() # Load from default path
# Load older file and update it automatically
config.load(filepath='old_config.toml', update_file=True)
except Exception as e:
print(f"Load failed: {e}")
(Mostly automatic. Use load(update_file=True)
to persist migrated state).
(Remains the same: provide key at init)
(Remains the same: access follows structure)
export_schema_with_values()
uses standard keys. import_config()
ignores __version__
in input data.
# Export (uses __version__, __schema__, __settings__)
full_state = config.export_schema_with_values()
# print(json.dumps(full_state, indent=2))
# Import (input data should be value structure, __version__ ignored)
update_data = {
"server": {"port": 8888},
"__version__": "ignored", # This key is skipped on import
# ... other values ...
}
config.import_config(update_data)
(Use cases remain the same)
(Advanced topics remain the same, focusing on custom handlers and potential future features)
(Contributing guidelines remain the same)
(License remains the same: Apache 2.0)
Built with ā¤ļø by ParisNeo with the help of Gemini 2.5
FAQs
A robust, schema-driven configuration management library for Python with encryption, versioning, nested sections, and multiple backends.
We found that configguard demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Ā It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Vite releases Rolldown-Vite, a Rust-based bundler preview offering faster builds and lower memory usage as a drop-in replacement for Vite.
Research
Security News
A malicious npm typosquat uses remote commands to silently delete entire project directories after a single mistyped install.
Research
Security News
Malicious PyPI package semantic-types steals Solana private keys via transitive dependency installs using monkey patching and blockchain exfiltration.