NekoConf - A cute configuration manager for your JSON and YAML configuration files
Project description
NekoConf
🐱 What is NekoConf?
NekoConf is a dynamic and flexible configuration management system for Python applications. It simplifies handling configuration files (YAML, JSON, TOML) and provides real-time updates, environment variable overrides, and schema validation.
| Feature | Description |
|---|---|
| Configuration as Code | Store configuration in human-readable YAML, JSON, or TOML files. |
| Centralized Management | Access and modify configuration via a Python API, CLI, or optional Web UI. |
| Dynamic Updates | React instantly to configuration changes using a built-in event system. |
| Environment Overrides | Seamlessly override file settings with environment variables. |
| Schema Validation | Ensure configuration integrity and prevent errors using JSON Schema. |
| Concurrency Safe | Uses file locking to prevent race conditions during file access. |
| Remote Configuration | Connect to a remote NekoConf server for centralized configuration. |
[!TIP] NekoConf is ideal for applications with complex configuration needs, microservice architectures, or any scenario where you need to update configuration without service restarts.
[!NOTE] This project is currently in beta. We welcome feedback and contributions!
🛠️ Prerequisites
- Python 3.11 or higher
- Docker (optional, for containerized deployment)
📦 Installation
NekoConf follows a modular design with optional dependencies for different features:
# Basic installation with core features
pip install nekoconf
# With web server (FastAPI-based)
pip install nekoconf[server]
# With schema validation
pip install nekoconf[schema]
# With remote configuration support
pip install nekoconf[remote]
# For development and testing
pip install nekoconf[dev]
# Install all optional features
pip install nekoconf[all]
Optional Features
| Feature | Extra | Dependencies | Purpose |
|---|---|---|---|
| Core | (none) | pyyaml, colorlog, tomli, tomli-w | Basic configuration operations |
| Web Server/API | server |
fastapi, uvicorn, jinja2, etc. | Run a web server to manage configuration |
| Schema Validation | schema |
jsonschema, rfc3987 | Validate configuration against JSON Schema |
| Remote Config | remote |
requests, websocket-client | Connect to a remote NekoConf server |
| Development Tools | dev |
pytest, pytest-cov, etc. | For development and testing |
| All Features | all |
All of the above | Complete installation with all features |
🚀 Quick Start
from nekoconf import NekoConf
# Initialize with configuration file path (creates file if it doesn't exist)
config = NekoConf("config.yaml", event_emission_enabled=True)
# Get configuration values (supports nested keys with dot notation)
db_host = config.get("database.host", default="localhost")
db_port = config.get("database.port", default=5432)
# Set configuration values
config.set("database.pool_size", 10)
config.set("features.dark_mode", True)
# Save changes to file
config.save()
# Register a handler to react to configuration changes
@config.on_change("database.*")
def handle_db_change(path, old_value, new_value, **kwargs):
print(f"Database configuration changed: {path}")
print(f" {old_value} -> {new_value}")
# Reconnect to database or apply changes...
🔧 Core Features
🔄 Configuration Management
Load, access, and modify configuration data using dot notation expressions.
# Load configuration from file (happens automatically on initialization)
config = NekoConf("config.yaml")
# Access values with type conversion
host = config.get("database.host")
port = config.get_int("database.port", default=5432)
is_enabled = config.get_bool("features.enabled", default=False)
# Update multiple values at once
config.update({
"logging": {
"level": "DEBUG",
"format": "%(asctime)s - %(levelname)s - %(message)s"
}
})
# Save to file
config.save()
🌍 Environment Variable Overrides
Override configuration with environment variables. By default, variables are mapped as:
database.host → NEKOCONF_DATABASE_HOST
# Override configuration values with environment variables
export NEKOCONF_DATABASE_HOST=production-db.example.com
export NEKOCONF_DATABASE_PORT=5433
export NEKOCONF_FEATURES_ENABLED=true
# These values will reflect environment variables automatically
config = NekoConf("config.yaml")
print(config.get("database.host")) # "production-db.example.com"
print(config.get_int("database.port")) # 5433
print(config.get_bool("features.enabled")) # True
You can customize the environment variable prefix and delimiter:
config = NekoConf(
"config.yaml",
env_prefix="MYAPP",
env_nested_delimiter="_"
)
The above would map database.host to MYAPP_DATABASE_HOST.
[!NOTE] See Environment Variables for more advanced configuration options.
📢 Event System
React to configuration changes in real-time:
from nekoconf import NekoConf, EventType
config = NekoConf("config.yaml", event_emission_enabled=True)
# React to any change to database configuration
@config.on_change("database.*")
def handle_db_change(path, old_value, new_value, **kwargs):
print(f"Database config {path} changed: {old_value} -> {new_value}")
# Reconnect to database or apply the change
# React to specific event types
@config.on_event([EventType.CREATE, EventType.UPDATE], "cache.*")
def handle_cache_config(path, new_value, **kwargs):
if event_type == EventType.CREATE:
print(f"New cache setting created: {path} = {new_value}")
else:
print(f"Cache setting updated: {path} = {new_value}")
# Update cache settings...
# Change configuration to trigger events
config.set("database.timeout", 30) # Triggers handle_db_change
config.set("cache.ttl", 600) # Triggers handle_cache_config
For more advanced event patterns, see Event Handling.
🌐 Remote Configuration
Connect to a remote NekoConf server for centralized configuration (requires nekoconf[remote]):
# Connect to a remote NekoConf server
config = NekoConf(
remote_url="https://config-server.example.com",
remote_api_key="secure-key",
remote_read_only=True, # Only read from server, don't push changes back
in_memory=True, # No local file, purely in-memory
event_emission_enabled=True # Enable event observer
)
# Use exactly the same API as with local files
db_host = config.get("database.host")
# React to changes from the remote server
@config.on_change("features.*")
def handle_feature_change(path, new_value, **kwargs):
print(f"Feature flag changed: {path} = {new_value}")
# Apply feature change...
You can also combine remote configuration with local files:
# Use remote configuration with local backup file
config = NekoConf(
config_path="local-backup.yaml", # Local backup file
remote_url="https://config-server.example.com",
remote_api_key="secure-key",
remote_read_only=False # Can push changes back to server
)
# Changes are first pushed to the remote server, then saved locally
config.set("api.timeout", 30)
config.save()
For more details and options, see Remote Configuration.
✅ Schema Validation
Ensure configuration integrity using JSON Schema (requires nekoconf[schema]):
# schema.json
{
"type": "object",
"properties": {
"database": {
"type": "object",
"required": ["host", "port"],
"properties": {
"host": {"type": "string"},
"port": {"type": "integer", "minimum": 1024}
}
}
},
"required": ["database"]
}
# Initialize with schema
config = NekoConf("config.yaml", schema_path="schema.json")
# Validate configuration
errors = config.validate()
if errors:
for error in errors:
print(f"Error: {error}")
# Set invalid value and validate
config.set("database.port", "not-a-port")
errors = config.validate()
print(errors) # Shows validation error
🖥️ Web UI & REST API
NekoConf includes a web server built with FastAPI to manage configuration remotely (requires nekoconf[server]):
from nekoconf import NekoConf, NekoConfOrchestrator
config = NekoConf("config.yaml")
server = NekoConfOrchestrator(config, api_key="secure-key")
server.run(host="0.0.0.0", port=8000)
Access at http://localhost:8000 for the web UI or use REST endpoints:
| Endpoint | Method | Description |
|---|---|---|
/api/config |
GET | Get entire configuration |
/api/config/{path} |
GET | Get specific configuration value |
/api/config/{path} |
POST | Set configuration value |
/api/config/{path} |
DELETE | Delete configuration value |
/api/config/validate |
POST | Validate configuration against schema |
/api/config/reload |
POST | Reload configuration from file |
The server also supports WebSocket connections for real-time configuration updates.
[!WARNING] Secure your API with an API key in production environments.
Learn more about the Web Server and REST API.
💻 Command-Line Interface
NekoConf provides a command-line interface for managing configuration:
# View help
nekoconf --help
# Start web server (requires nekoconf[server])
nekoconf server --config config.yaml --port 8000 --api-key "secure-key"
# Get configuration value
nekoconf get database.host --config config.yaml
# Get entire configuration as JSON
nekoconf get --config config.yaml --format json
# Set configuration value
nekoconf set database.port 5432 --config config.yaml
# Delete configuration value
nekoconf delete old.setting --config config.yaml
# Validate configuration (requires nekoconf[schema])
nekoconf validate --config config.yaml --schema schema.json
# Import configuration from another file
nekoconf import new-values.json --config config.yaml
# Connect to a remote NekoConf server (requires nekoconf[remote])
nekoconf connect http://config-server:8000 --api-key "secure-key" --watch
Remote Configuration via CLI
You can connect to a remote NekoConf server directly from the command line:
# Connect to a remote server and watch for config changes
nekoconf connect http://config-server:8000 --watch --format json
# Get a value from remote server
nekoconf get api.timeout --remote-url http://config-server:8000 --remote-api-key "secure-key"
# Update a value on the remote server
nekoconf set cache.ttl 600 --remote-url http://config-server:8000 --remote-api-key "secure-key"
See the CLI Reference for all available commands and options.
🔌 Integration Examples
🌶️ Flask Integration
from flask import Flask
from nekoconf import NekoConf
app = Flask(__name__)
config_manager = NekoConf("flask_app_config.yaml", event_emission_enabled=True)
# Use configuration values to configure Flask
app.config["DEBUG"] = config_manager.get_bool("app.debug", default=False)
app.config["SECRET_KEY"] = config_manager.get_str("app.secret_key", default="dev-key")
# Listen for configuration changes
@config_manager.on_change("app.*")
def handle_app_config_change(path, new_value, **kwargs):
if path == "app.debug":
app.config["DEBUG"] = new_value
elif path == "app.secret_key":
app.config["SECRET_KEY"] = new_value
# Note: Some settings require app restart
@app.route('/')
def index():
return f"API Version: {config_manager.get('app.version', 'v1.0')}"
⚡ FastAPI Integration
from fastapi import FastAPI, Depends
from nekoconf import NekoConf
config_manager = NekoConf("fastapi_config.yaml", event_emission_enabled=True)
app = FastAPI(title=config_manager.get("api.title", "My API"))
# Dependency to access configuration
def get_config():
return config_manager
@app.get("/")
def read_root(config: NekoConf = Depends(get_config)):
return {"version": config.get("api.version", "1.0")}
# React to configuration changes
@config_manager.on_change("rate_limit.*")
async def update_rate_limits(path, new_value, **kwargs):
# Update rate limiting middleware configuration
print(f"Rate limit updated: {path} = {new_value}")
🎸 Django Integration
# settings.py
from pathlib import Path
from nekoconf import NekoConf
# Initialize configuration
config_manager = NekoConf("django_settings.yaml")
# Use configuration values in Django settings
DEBUG = config_manager.get_bool("django.debug", default=False)
SECRET_KEY = config_manager.get_str("django.secret_key", required=True)
ALLOWED_HOSTS = config_manager.get_list("django.allowed_hosts", default=["localhost"])
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': config_manager.get("database.name", "django"),
'USER': config_manager.get("database.user", "django"),
'PASSWORD': config_manager.get("database.password", ""),
'HOST': config_manager.get("database.host", "localhost"),
'PORT': config_manager.get_int("database.port", 5432),
}
}
# For dynamic reconfiguration, create an app config to listen for changes
📱 Microservices Integration with Remote Config
# In your microservice
from nekoconf import NekoConf
# Connect to the central configuration server
config = NekoConf(
remote_url="http://config-service:8000",
remote_api_key="service-specific-key",
in_memory=True, # No local file needed
event_emission_enabled=True
)
# Use configuration
service_port = config.get_int("service.port", 8080)
feature_flags = config.get("features", {})
# React to configuration changes in real-time
@config.on_change("features.*")
def handle_feature_change(path, **kwargs):
print(f"Feature flag changed: {path}")
# Apply feature change dynamically
📚 Documentation
NekoConf offers comprehensive documentation for all its core features and advanced usage. For a better experience, each major topic is documented in a dedicated markdown file under the docs/ directory. See below for quick links and summaries:
| Topic | Description |
|---|---|
| Environment Variables | How to override config with environment variables, advanced patterns, and customization. |
| Event System | Real-time event handling, usage patterns, and best practices. |
| Web Server & REST API | Running the FastAPI server, REST API endpoints, Web UI, and security. |
| CLI Reference | Full command-line usage, options, and examples. |
| Schema Validation | Using JSON Schema for config validation, error handling, and tips. |
| Security Considerations | API key usage, best practices, and deployment security. |
| Advanced Usage | Deep dives: concurrency, integration, dynamic reload, and more. |
| Remote Configuration | Connecting to remote NekoConf servers, synchronization, and deployment patterns. |
For installation, quick start, and integration examples, see above sections. For detailed guides, visit the linked docs.
👩💻 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
❤️ Discord Community
[!NOTE] Need support? Contact k3scat@gmail.com or join our discord community at Nya Foundation
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
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 nekoconf-1.1.0.tar.gz.
File metadata
- Download URL: nekoconf-1.1.0.tar.gz
- Upload date:
- Size: 155.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
22d4559a75be6b6efc569014ee033aa949c72cc2bd5b921e84c7268d27e1bdd9
|
|
| MD5 |
df912652519ea5a54035980673a91682
|
|
| BLAKE2b-256 |
8178034ff2c4ad81b90ffa5868cd54a16eb3de575a20c1271800e19025588214
|
Provenance
The following attestation bundles were made for nekoconf-1.1.0.tar.gz:
Publisher:
publish.yml on Nya-Foundation/NekoConf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nekoconf-1.1.0.tar.gz -
Subject digest:
22d4559a75be6b6efc569014ee033aa949c72cc2bd5b921e84c7268d27e1bdd9 - Sigstore transparency entry: 226670568
- Sigstore integration time:
-
Permalink:
Nya-Foundation/NekoConf@4f0930e266f41039ec27f1776fdb3791c7e6028f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Nya-Foundation
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4f0930e266f41039ec27f1776fdb3791c7e6028f -
Trigger Event:
push
-
Statement type:
File details
Details for the file nekoconf-1.1.0-py3-none-any.whl.
File metadata
- Download URL: nekoconf-1.1.0-py3-none-any.whl
- Upload date:
- Size: 115.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6c63bd7b4781a6c1e498e1b01ba9a0b952cc9ce4c61271205fc7cd4233ef6ce
|
|
| MD5 |
a427ae510ebcf630f14e48b406356030
|
|
| BLAKE2b-256 |
9248aeccc9de387dc5451609f4d02965bec6a1de3e5fdb45091147004319ae5e
|
Provenance
The following attestation bundles were made for nekoconf-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on Nya-Foundation/NekoConf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nekoconf-1.1.0-py3-none-any.whl -
Subject digest:
f6c63bd7b4781a6c1e498e1b01ba9a0b952cc9ce4c61271205fc7cd4233ef6ce - Sigstore transparency entry: 226670569
- Sigstore integration time:
-
Permalink:
Nya-Foundation/NekoConf@4f0930e266f41039ec27f1776fdb3791c7e6028f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Nya-Foundation
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4f0930e266f41039ec27f1776fdb3791c7e6028f -
Trigger Event:
push
-
Statement type: