Module: pytest_jux.config
Purpose: Configuration management with multiple sources (CLI, environment, files)
Version: 0.1.9+
The config module provides centralized configuration management for pytest-jux. It supports loading configuration from multiple sources with proper precedence, validation using Pydantic, and environment-specific settings.
- Multi-Source Configuration: Load from CLI arguments, environment variables, and config files
- Validation: Validate configuration using Pydantic models
- Environment Support: Production, staging, development configurations
- XDG Compliance: Config files in XDG-compliant locations
- Configuring pytest-jux plugin behavior
- Managing signing keys and API endpoints
- Setting up multi-environment configurations
- Programmatically accessing configuration
plugin: Uses config to configure pytest hooksstorage: Uses config for storage mode settingsmetadata: Uses config for metadata collection settings
.. automodule:: pytest_jux.config
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
Main configuration class (Pydantic model).
.. autoclass:: pytest_jux.config.JuxConfig
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
Example:
from pathlib import Path
from pytest_jux.config import JuxConfig
# Create configuration
config = JuxConfig(
private_key_path=Path("~/.ssh/jux/key.pem").expanduser(),
certificate_path=Path("~/.ssh/jux/cert.pem").expanduser(),
environment="production",
storage_mode="auto"
)
print(f"Environment: {config.environment}")
print(f"Key: {config.private_key_path}")Configuration manager for loading from multiple sources.
.. autoclass:: pytest_jux.config.ConfigManager
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
Example:
from pytest_jux.config import ConfigManager
# Load configuration from all sources
manager = ConfigManager()
config = manager.load()
print(f"Environment: {config.environment}")
print(f"Storage mode: {config.storage_mode}")Configuration is loaded from multiple sources with the following precedence (highest to lowest):
- Command-line arguments (highest priority)
- Environment variables (
JUX_*prefix) - Config files (TOML format)
- Default values (lowest priority)
Default locations (searched in order):
$XDG_CONFIG_HOME/pytest-jux/config.toml(default:~/.config/pytest-jux/config.toml)~/.config/jux/config.toml/etc/jux/config.toml
Example config.toml:
# pytest-jux configuration
[jux]
environment = "production"
storage_mode = "auto"
[jux.signing]
private_key_path = "~/.ssh/jux/jux-signing-key.pem"
certificate_path = "~/.ssh/jux/jux-signing-key.crt"
[jux.api]
# API configuration (future)
# base_url = "https://jux.example.com/api"
# timeout = 30| Option | Type | Default | Description |
|---|---|---|---|
environment |
str |
"production" |
Environment name (production, staging, development) |
storage_mode |
str |
"auto" |
Storage mode (auto, disabled) |
private_key_path |
Path |
None |
Path to private key for signing |
certificate_path |
Path |
None |
Path to X.509 certificate |
config_file |
Path |
None |
Custom config file path |
All options can be set via environment variables with JUX_ prefix:
| Variable | Option | Example |
|---|---|---|
JUX_ENVIRONMENT |
environment |
export JUX_ENVIRONMENT=staging |
JUX_STORAGE_MODE |
storage_mode |
export JUX_STORAGE_MODE=disabled |
JUX_KEY_PATH |
private_key_path |
export JUX_KEY_PATH=~/.ssh/jux/key.pem |
JUX_CERT_PATH |
certificate_path |
export JUX_CERT_PATH=~/.ssh/jux/cert.pem |
JUX_CONFIG_FILE |
config_file |
export JUX_CONFIG_FILE=/etc/jux/prod.toml |
from pytest_jux.config import ConfigManager
# Load from all sources (CLI, env, files, defaults)
manager = ConfigManager()
config = manager.load()
print(f"Environment: {config.environment}")
print(f"Storage: {config.storage_mode}")from pathlib import Path
from pytest_jux.config import JuxConfig
# Create configuration object
config = JuxConfig(
environment="staging",
private_key_path=Path("~/.ssh/jux-staging/key.pem").expanduser(),
certificate_path=Path("~/.ssh/jux-staging/cert.pem").expanduser(),
storage_mode="auto"
)
# Use configuration
if config.private_key_path.exists():
print(f"Key found: {config.private_key_path}")from pytest_jux.config import ConfigManager
import os
# Set environment via environment variable
os.environ["JUX_ENVIRONMENT"] = "development"
manager = ConfigManager()
config = manager.load()
if config.environment == "development":
print("Development mode - using test keys")
elif config.environment == "production":
print("Production mode - using production keys")# config.toml
[jux]
environment = "production" # Default environment
[jux.environments.production]
private_key_path = "~/.ssh/jux/prod-key.pem"
certificate_path = "~/.ssh/jux/prod-cert.pem"
storage_mode = "auto"
[jux.environments.staging]
private_key_path = "~/.ssh/jux/staging-key.pem"
certificate_path = "~/.ssh/jux/staging-cert.pem"
storage_mode = "auto"
[jux.environments.development]
private_key_path = "~/.ssh/jux/dev-key.pem"
certificate_path = "~/.ssh/jux/dev-cert.pem"
storage_mode = "disabled" # Don't cache in devConfiguration is validated using Pydantic:
- private_key_path: Must be a valid Path object (if provided)
- certificate_path: Must be a valid Path object (if provided)
- environment: Must be a string
- storage_mode: Must be "auto" or "disabled"
from pytest_jux.config import JuxConfig
from pydantic import ValidationError
try:
config = JuxConfig(
storage_mode="invalid" # Invalid value
)
except ValidationError as e:
print(f"Validation error: {e}")
# Output: Input should be 'auto' or 'disabled'The config module is used by the jux-config CLI command:
# Show current configuration
jux-config show
# Show configuration in JSON format
jux-config show --json
# Edit configuration file
jux-config edit
# Validate configuration
jux-config validate
# Use custom config file
jux-config show --config /etc/jux/custom.tomlSee jux-config CLI reference for details.
Given:
- Config file:
environment = "production" - Environment variable:
export JUX_ENVIRONMENT=staging - CLI argument:
--environment development
Result:
# CLI wins (highest precedence)
config.environment == "development"When no configuration is provided:
from pytest_jux.config import JuxConfig
# Default configuration
config = JuxConfig()
assert config.environment == "production"
assert config.storage_mode == "auto"
assert config.private_key_path is None
assert config.certificate_path is NoneConfiguration is automatically loaded when pytest-jux plugin is activated:
# Via pytest command line
pytest --jux-key ~/.ssh/jux/key.pem --jux-cert ~/.ssh/jux/cert.pem
# Via environment variables
export JUX_KEY_PATH=~/.ssh/jux/key.pem
export JUX_CERT_PATH=~/.ssh/jux/cert.pem
pytest
# Via pytest.ini
# [pytest]
# jux_key_path = ~/.ssh/jux/key.pem
# jux_cert_path = ~/.ssh/jux/cert.pem
pytestDO NOT commit sensitive configuration to version control:
- ❌ Private keys
- ❌ API tokens
- ❌ Passwords
Best Practices:
- Use environment variables for sensitive values
- Store config files outside repository
- Use
.gitignoreto exclude config files - Restrict file permissions (
chmod 600 config.toml)
# Exclude sensitive configuration
config.toml
*.pem
*.key
.env| Error | Cause | Solution |
|---|---|---|
FileNotFoundError |
Config file not found | Check file path or create config file |
ValidationError |
Invalid configuration value | Fix configuration value |
PermissionError |
Cannot read config file | Check file permissions |
TOMLDecodeError |
Invalid TOML syntax | Fix TOML syntax errors |
Example:
from pytest_jux.config import ConfigManager
from pydantic import ValidationError
try:
manager = ConfigManager(config_file="/nonexistent.toml")
config = manager.load()
except FileNotFoundError as e:
print(f"Config file not found: {e}")
except ValidationError as e:
print(f"Invalid configuration: {e}")- jux-config CLI: Configuration management command
- Multi-Environment Configuration Guide: How-to guide for multi-environment setup
- Pydantic Documentation: Pydantic validation library
Module Path: pytest_jux.config
Source Code: pytest_jux/config.py
Tests: tests/test_config.py
Last Updated: 2025-10-20