Metadata-Version: 2.4
Name: confbox
Version: 0.1.4
Summary: Cross-platform application configuration manager for Python
Home-page: https://github.com/jmmirabile/confbox
Author: Jeff Mirabile
Author-email: Jeff Mirabile <jmmirabile@users.noreply.github.com>
License: MIT
Project-URL: Homepage, https://github.com/jmmirabile/confbox
Project-URL: Repository, https://github.com/jmmirabile/confbox
Project-URL: Issues, https://github.com/jmmirabile/confbox/issues
Keywords: configuration,config,yaml,settings,cross-platform,appconfig
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Installation/Setup
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyyaml>=5.1
Provides-Extra: dev
Requires-Dist: pytest>=6.0; extra == "dev"
Requires-Dist: pytest-cov>=2.0; extra == "dev"
Requires-Dist: black>=21.0; extra == "dev"
Requires-Dist: mypy>=0.900; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# ConfBox

[![PyPI version](https://badge.fury.io/py/confbox.svg)](https://badge.fury.io/py/confbox)

A Python module for managing application configuration files in OS-specific standard directories.

## Features

- **Cross-platform**: Automatically uses the correct configuration directory for each OS:
  - Linux: `~/.config/<app_name>`
  - macOS: `~/Library/Application Support/<app_name>`
  - Windows: `%LOCALAPPDATA%\Programs\<app_name>`
- **YAML-based**: Store configuration in human-readable YAML format
- **Simple API**: Easy-to-use interface for reading, updating, and storing config
- **Nested config**: Support for nested configuration using dot notation
- **Auto-save**: Optional automatic saving after each update
- **Type hints**: Full type hint support for better IDE integration

## Installation

```bash
pip install confbox
```

Or install from source:

```bash
git clone https://github.com/jmmirabile/confbox.git
cd confbox
pip install -e .
```

## Quick Start

```python
from confbox import ConfBox

# Initialize configuration for your app
config = ConfBox("myapp")

# Set configuration values
config.set("server.host", "localhost")
config.set("server.port", 8080)
config.set("database.url", "postgresql://localhost/mydb")

# Save configuration
config.save()

# Later, from anywhere in your application:
config = ConfBox("myapp")
host = config.get("server.host")  # "localhost"
port = config.get("server.port")  # 8080
```

## Usage Examples

### Basic Configuration Management

```python
from confbox import ConfBox

# Create config (auto-creates directory and file)
config = ConfBox("myapp")

# Set values
config.set("api_key", "secret-key-123")
config.set("debug", True)
config.set("max_retries", 3)

# Save to disk
config.save()

# Get values
api_key = config.get("api_key")
debug = config.get("debug", default=False)
```

### Nested Configuration

```python
# Set nested values using dot notation
config.set("database.host", "localhost")
config.set("database.port", 5432)
config.set("database.credentials.username", "admin")
config.set("database.credentials.password", "secret")

# Get nested values
db_host = config.get("database.host")
db_user = config.get("database.credentials.username")

# Update multiple values at once
config.update({
    "server": {
        "host": "0.0.0.0",
        "port": 8080,
        "workers": 4
    }
})
config.save()
```

### Auto-save Mode

```python
# Enable auto-save to persist changes immediately
config = ConfBox("myapp", auto_save=True)

# Changes are automatically saved
config.set("last_updated", "2025-01-24")  # Automatically saved
```

### Working with Configuration Files

```python
# Use custom config filename
config = ConfBox("myapp", config_filename="settings.yaml")

# Check if config exists
if config.exists():
    print("Config found at:", config.config_path)

# Get all config as dictionary
all_config = config.to_dict()

# Clear all configuration
config.clear()
config.save()

# Delete specific keys
config.delete("old_setting")
```

### Multiple Configuration Files

You can create multiple ConfBox instances for the same app with different config files:

```python
# Main application config
config = ConfBox("myapp")
# → ~/.config/myapp/app-config.yaml

# API configuration
api_config = ConfBox("myapp", config_filename="api.yaml")
# → ~/.config/myapp/api.yaml

# Database configuration
db_config = ConfBox("myapp", config_filename="database.yaml")
# → ~/.config/myapp/database.yaml

# All configs live in the same app directory
# This allows you to separate concerns while keeping configs organized
config.set("app.version", "1.0.0")
api_config.set("endpoint", "https://api.example.com")
db_config.set("host", "localhost")

config.save()
api_config.save()
db_config.save()
```

### Get Configuration Directory

```python
from confbox import get_app_config_dir

# Get the config directory path for your app
config_dir = get_app_config_dir("myapp")
print(f"Config directory: {config_dir}")

# Create custom files in the config directory
log_file = config_dir / "app.log"
cache_dir = config_dir / "cache"
```

## Example: Command-Line Tool

```python
#!/usr/bin/env python3
"""Example CLI tool using confbox."""

from confbox import ConfBox

def main():
    # Config is loaded from standard location regardless of CWD
    config = ConfBox("mytool")

    # First run setup
    if not config.get("initialized"):
        print("First run detected. Setting up configuration...")
        config.set("initialized", True)
        config.set("version", "1.0.0")
        config.set("user.name", input("Enter your name: "))
        config.save()

    # Use configuration
    username = config.get("user.name")
    print(f"Hello, {username}!")

    # Update last run time
    from datetime import datetime
    config.set("last_run", datetime.now().isoformat())
    config.save()

if __name__ == "__main__":
    main()
```

## API Reference

### `ConfBox`

Main class for managing application configuration.

**Constructor:**
```python
ConfBox(
    app_name: str,
    config_filename: str = "app-config.yaml",
    auto_create: bool = True,
    auto_save: bool = False
)
```

**Methods:**
- `load()`: Load configuration from file
- `save()`: Save configuration to file
- `get(key, default=None)`: Get a config value (supports dot notation)
- `set(key, value)`: Set a config value (supports dot notation)
- `delete(key)`: Delete a config key
- `update(data)`: Update config with a dictionary
- `to_dict()`: Get entire config as dictionary
- `exists()`: Check if config file exists
- `clear()`: Clear all configuration

### `get_app_config_dir`

Get the OS-specific configuration directory.

```python
get_app_config_dir(app_name: str, create: bool = True) -> Path
```

## Configuration File Location

The configuration file location depends on your operating system:

| OS | Default Location |
|----|-----------------|
| Linux | `~/.config/<app_name>/app-config.yaml` |
| macOS | `~/Library/Application Support/<app_name>/app-config.yaml` |
| Windows | `%LOCALAPPDATA%\Programs\<app_name>\app-config.yaml` |

## Development

Install development dependencies:

```bash
pip install -e ".[dev]"
```

Run tests:

```bash
pytest
```

Format code:

```bash
black confbox
```

Type checking:

```bash
mypy confbox
```

## License

MIT License - see LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.
