Python Tool Configuration
pytoolconfig is a Python library designed for simple and declarative definition of tool configurations, typically read from `pyproject.toml` or other config files. It provides a `ToolConfig` class to define configuration schemas with type hints and default values. The current version is 1.3.1, and it maintains a moderate release cadence, with minor updates every few months addressing features and maintenance.
Warnings
- breaking Python 3.7 support has been officially dropped starting with version 1.3.1. Users on Python 3.7 will need to upgrade their Python interpreter to 3.8 or newer to use the latest versions of pytoolconfig.
- gotcha When using `ToolConfig.load()`, pytoolconfig attempts to load configuration from multiple sources (e.g., command line arguments, environment variables, configuration files like `pyproject.toml` or `.{app_name}.yaml`). The order of precedence for these sources can be crucial and might lead to unexpected values if not understood.
- gotcha The `Field` object from `pytoolconfig` is used to provide metadata (like `default` and `help`) alongside type hints. Users familiar with `dataclasses.field` or `pydantic.Field` should note the specific parameters and behavior, as they may not be fully interchangeable.
Install
-
pip install pytoolconfig
Imports
- ToolConfig
from pytoolconfig import ToolConfig
- Field
from pytoolconfig import Field
Quickstart
from pytoolconfig import ToolConfig, Field
import os
# Define your configuration schema
class MyToolConfig(ToolConfig):
project_name: str = Field(default="my-default-project", help="Name of the project")
debug_mode: bool = Field(default=False, help="Enable debug logging")
output_dir: str = Field(default="./output", help="Directory for output files")
# Simulate a configuration file (e.g., .toolconfig.yaml or pyproject.toml)
# In a real scenario, this would be loaded from disk.
# For demonstration, we'll manually create a dummy config.
# In practice, `from_file`, `from_pyproject`, or `load` would be used.
# Example of loading from a dictionary, simulating file content:
dummy_config_data = {
"tool": {
"mytool": {
"project_name": os.environ.get("MYTOOL_PROJECT_NAME", "override-from-env"),
"debug_mode": True
}
}
}
# Load configuration for 'mytool'
# The library would typically discover this automatically from `load()` or `from_pyproject()`
config = MyToolConfig.load(app_name="mytool", config_data=dummy_config_data)
print(f"Project Name: {config.project_name}")
print(f"Debug Mode: {config.debug_mode}")
print(f"Output Directory: {config.output_dir}")
# Demonstrating default value for output_dir which was not in dummy_config_data
assert config.output_dir == "./output"
# Demonstrating override from dummy_config_data (or environment variable if set)
assert config.project_name == (os.environ.get("MYTOOL_PROJECT_NAME", "override-from-env"))
assert config.debug_mode is True