Usage Guide
This guide provides more detailed information on how to use Nubby in your applications.
Configuration File Definition
Basic File Definition
To define a configuration file, use the new_file_model function:
from nubby.models import new_file_model
# Create a file definition for a file named "app_config"
file_definition = new_file_model("app_config")
This will look for a file named app_config with any of the supported extensions (.json, .yaml, .yml, .toml) in the search paths.
Custom Name Generation
You can customize how section names are generated by providing a name_generator function:
# Use snake_case for section names
def to_snake_case(name):
import re
return re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
file_definition = new_file_model("config", name_generator=to_snake_case)
Section Definition
Basic Section Definition
To define a section in your configuration file, use the section decorator:
from dataclasses import dataclass
@file_definition.section("database")
@dataclass
class DatabaseConfig:
host: str
port: int
username: str
password: str
Automatic Section Naming
If you don't provide a section name, Nubby will use the class name (possibly transformed by the name_generator):
@file_definition.section() # Will use "database_config" with snake_case generator
@dataclass
class DatabaseConfig:
host: str
port: int
username: str
password: str
Nested Configuration
You can create nested configuration structures using dataclasses:
@dataclass
class ConnectionDetails:
host: str
port: int
@file_definition.section("database")
@dataclass
class DatabaseConfig:
connection: ConnectionDetails
username: str
password: str
Using Configuration
Basic Dependency Injection
Use Bevy's dependency injection to access your configuration:
from bevy import inject, dependency
@inject
def connect_to_database(db_config: DatabaseConfig = dependency()):
# db_config is automatically loaded from the configuration file
print(f"Connecting to {db_config.host}:{db_config.port}")
# ... connection logic ...
Manual Access
You can also access configuration manually:
from nubby import get_active_controller
# Get a configuration instance
db_config = get_active_controller().get_model(DatabaseConfig)
Configuration File Management
Search Paths
By default, Nubby looks for configuration files in the current working directory. You can add additional search paths:
from nubby import get_active_controller
# Add a search path
get_active_controller().add_path("/etc/myapp")
get_active_controller().add_path("~/.config/myapp")
Saving Configuration
You can save changes to a configuration back to the file:
from nubby import get_active_controller
# After modifying the configuration
db_config.port = 5433
get_active_controller().save(db_config)
Custom Loaders
You can create custom loaders for other file formats:
from nubby.loaders import ConfigLoader
from pathlib import Path
from typing import Any
class MyCustomLoader(ConfigLoader):
extensions = {"mycfg"}
def __init__(self, path: Path):
super().__init__(path)
self._data = None
def load(self, *args) -> dict[str, Any]:
# Implement loading logic
...
def write(self, data: dict[str, Any]):
# Implement writing logic
...
# Use the custom loader
from nubby import setup_controller
setup_controller([MyCustomLoader])
Advanced Topics
Multiple Configuration Files
You can define multiple configuration files:
app_config = new_file_model("app_config")
user_config = new_file_model("user_config")
@app_config.section("database")
@dataclass
class DatabaseConfig:
host: str
port: int
@user_config.section("preferences")
@dataclass
class UserPreferences:
theme: str
language: str
Configuration Validation
You can add validation to your configuration using dataclass post-init:
from dataclasses import dataclass
@file_definition.section("database")
@dataclass
class DatabaseConfig:
host: str
port: int
def __post_init__(self):
if not self.host:
raise ValueError("Host cannot be empty")
if not 1 <= self.port <= 65535:
raise ValueError(f"Port must be between 1 and 65535, got {self.port}")
Environment Variable Integration
You can integrate environment variables with your configuration: