### YAML Configuration File Example - For Transformation Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Example YAML file with string values that will be transformed by the custom loader. ```yaml name: "example" value: "test" ``` -------------------------------- ### Typical Config Locations Example Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/fallback_config.md An example demonstrating a real-world use case for `use_fallback_config` with common configuration file locations, ordered by priority from highest to lowest. ```python @app.command() @use_fallback_config(fallback_files=[ "./myapp.yml", # local project config (highest priority) "~/.config/myapp/config.yml", # user config "/etc/myapp/config.yml", # system config (lowest priority) ]) def main(...): ... ``` -------------------------------- ### Install Dependencies with uv Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Installs all project dependencies, including optional extras, using the uv package manager. ```bash uv sync --all-extras ``` -------------------------------- ### Quickstart: Add YAML Configuration to Typer App Source: https://github.com/maxb2/typer-config/blob/main/docs/index.md Demonstrates how to use the `@use_yaml_config()` decorator to enable YAML configuration for a Typer command. Ensure this decorator is placed after `@app.command()`. ```python import typer from typer_config import use_yaml_config # other formats available (1) app = typer.Typer() @app.command() @use_yaml_config() # MUST BE AFTER @app.command() (2) def main(name: str, greeting: str = "Hello"): ... if __name__ == "__main__": app() ``` -------------------------------- ### YAML Configuration File Example - Defaults Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Example of a default YAML configuration file. These values are used if not overridden by other specified configuration files. ```yaml name: "Guest" age: 18 ``` -------------------------------- ### Python Code Example - Basic Typer App with Config Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Illustrates a basic Typer application that uses configuration files. This example demonstrates how to integrate configuration loading into a Typer CLI. ```python from typer import Typer from typer_config import use_yaml_config app = Typer() @app.command() @use_yaml_config(config_files=["config.yaml"]) def main(name: str, age: int): """A simple CLI app that greets you and tells you your age.""" print(f"Hello {name}, you are {age} years old.") if __name__ == "__main__": app() ``` -------------------------------- ### Simplify long commands with config file Source: https://github.com/maxb2/typer-config/blob/main/README.md Example showing how a long command with multiple options can be simplified by using a configuration file. ```bash # Long commands like this: $ my-typer-app --opt1 foo --opt2 bar arg1 arg2 # Can become this: $ my-typer-app --config config.yml ``` -------------------------------- ### Install Typer Config with all optional dependencies Source: https://github.com/maxb2/typer-config/blob/main/docs/install.md Install Typer Config with all available optional dependencies, enabling support for all file formats. ```bash $ pip install typer-config[all] # includes all optional dependencies ``` -------------------------------- ### Install typer-config with all extras Source: https://github.com/maxb2/typer-config/blob/main/README.md Install the package with optional dependencies for YAML, TOML, and Dotenv file support. Omit optional dependencies if not needed. ```bash $ pip install typer-config[all] ``` -------------------------------- ### Bash Command Simplification Example Source: https://github.com/maxb2/typer-config/blob/main/docs/index.md Illustrates how a long Typer CLI command can be simplified by using a configuration file. ```bash # Long commands like this: $ my-typer-app --greeting Hello --suffix "!" World # Can become this: $ my-typer-app --config config.yml ``` -------------------------------- ### YAML Configuration File Example Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Example of a YAML configuration file used with typer-config. This file defines parameters that can be loaded by the CLI application. ```yaml name: "World" age: 42 ``` -------------------------------- ### Python Code Example - Dumping Configuration Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Demonstrates how to dump the current configuration to a file using typer-config. This is useful for inspecting or saving the effective configuration. ```python from typer import Typer, Option from typer_config import use_config, dump_config app = Typer() @app.command() @use_config(config_files=["config.yaml"]) def main( name: str = Option("World", "--name", "-n"), age: int = Option(42, "--age", "-a"), config_file: str = Option("output.yaml", "--config-file", "-c"), ): """A simple CLI app that greets you and tells you your age.""" print(f"Hello {name}, you are {age} years old.") dump_config(config_file, name=name, age=age) if __name__ == "__main__": app() ``` -------------------------------- ### Example Configuration File Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/schema.md This YAML file provides the configuration values for the Typer application. It must conform to the schema defined in the Python script. ```yaml name: World greeting: Hello suffix: "!" ``` -------------------------------- ### Command-Line Invocation Examples Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/default_config.md These bash commands demonstrate how to run the Typer application with and without providing custom arguments or a configuration file. The first two examples show default behavior and overriding 'name', while the latter two show overriding 'greeting' and specifying an alternative config file. ```bash $ python simple_app.py Hello, World! $ python simple_app.py Alice Hello, Alice! $ python simple_app.py --greeting Hi Hi, World! $ python simple_app.py --config other.yml Hi, Alice!! ``` -------------------------------- ### CLI execution examples Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/pyproject.md These bash commands demonstrate how to run the Typer CLI application with different configurations, showing default behavior, argument overrides, and loading from an alternative TOML file. ```bash $ ls . my_tool.py other.toml pyproject.toml $ python my_tool.py Hello, World! $ python my_tool.py Alice Hello, Alice! $ python my_tool.py --config other.toml Hi, Alice!! ``` -------------------------------- ### Python Code Example - Using Multiple Config Files Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Demonstrates how to use multiple configuration files with typer-config. The library merges configurations, with later files overriding earlier ones. ```python from typer import Typer from typer_config import use_multifile_config app = Typer() @app.command() @use_multifile_config( config_files=["config.yaml", "secrets.yaml"], default_config_files=["default.yaml"], ) def main(name: str, age: int, secret_key: str): """A simple CLI app that greets you and tells you your age.""" print(f"Hello {name}, you are {age} years old.") print(f"Secret key: {secret_key}") if __name__ == "__main__": app() ``` -------------------------------- ### Install Typer Config Source: https://github.com/maxb2/typer-config/blob/main/docs/install.md Install the base Typer Config package. Python version 3.10 or higher is required. This installation only supports JSON configuration files. ```bash $ pip install typer-config ``` -------------------------------- ### Python Code Example - Fallback Configuration Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Shows how to use fallback configuration files with typer-config. This allows for a layered approach to configuration, ensuring defaults are always available. ```python from typer import Typer from typer_config import use_fallback_config app = Typer() @app.command() @use_fallback_config( config_files=["config.yaml"], fallback_config_files=["default.yaml"], ) def main(name: str, age: int): """A simple CLI app that greets you and tells you your age.""" print(f"Hello {name}, you are {age} years old.") if __name__ == "__main__": app() ``` -------------------------------- ### Python Code Example - Lazy Import Handling Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Demonstrates the use of lazy imports for optional dependencies in typer-config. This prevents import errors if optional libraries like PyYAML or TOML are not installed. ```python from typer_config.__optional_imports import try_import # Attempt to import pyyaml, returns None if not available yaml = try_import("yaml") def load_yaml_config(file_path: str): if yaml: with open(file_path, 'r') as f: return yaml.safe_load(f) else: raise ImportError("PyYAML is required for YAML loading but not installed.") ``` -------------------------------- ### Install Typer Config with TOML support Source: https://github.com/maxb2/typer-config/blob/main/docs/install.md Install Typer Config with the optional dependency for TOML file support. This includes the TOML library. ```bash $ pip install typer-config[toml] # includes toml ``` -------------------------------- ### YAML Configuration File Example - Nested Section Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Example of a YAML configuration file with a nested structure. The 'app.settings' section is targeted for loading by the CLI application. ```yaml app: settings: setting1: "value1" setting2: 123 other_section: key: "value" ``` -------------------------------- ### YAML Configuration File Example - For Section Extraction Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md YAML file containing a 'settings' section to be extracted and transformed by the custom loader. ```yaml settings: setting1: "example" setting2: 123 other_data: key: "value" ``` -------------------------------- ### Install Typer Config with YAML support Source: https://github.com/maxb2/typer-config/blob/main/docs/install.md Install Typer Config with the optional dependency for YAML file support. This includes the PyYAML library. ```bash $ pip install typer-config[yaml] # includes pyyaml ``` -------------------------------- ### Install Typer Config with Python Dotenv support Source: https://github.com/maxb2/typer-config/blob/main/docs/install.md Install Typer Config with the optional dependency for reading .env files. This includes the python-dotenv library. ```bash $ pip install typer-config[python-dotenv] # includes python-dotenv ``` -------------------------------- ### Python Code Example - Nested Configuration Section Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Illustrates how to load a specific section from a nested configuration file using typer-config. This allows for better organization of complex configurations. ```python from typer import Typer from typer_config import use_config, ConfigDict app = Typer() @app.command() @use_config(config_files=["config.yaml"], config_section="app.settings") def main(setting1: str, setting2: int): """A simple CLI app that uses a nested config section.""" print(f"Setting 1: {setting1}") print(f"Setting 2: {setting2}") if __name__ == "__main__": app() ``` -------------------------------- ### YAML Configuration File Example - Secrets Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Example of a YAML configuration file containing sensitive information. This file would typically be used in conjunction with other configuration files. ```yaml secret_key: "my-super-secret-key" ``` -------------------------------- ### Quickstart: Add YAML config to Typer app Source: https://github.com/maxb2/typer-config/blob/main/README.md Use the `@use_yaml_config` decorator after `@app.command()` to add a `--config CONFIG_FILE` option to your Typer application. This decorator enables loading parameters from a YAML file. ```python import typer from typer_config import use_yaml_config app = typer.Typer() @app.command() @use_yaml_config() # MUST BE AFTER @app.command() def main(foo: FooType): ... if __name__ == "__main__": app() ``` -------------------------------- ### Python Code Example - Custom Loader Transformation Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Shows how to apply custom transformations to configuration data during loading using typer-config. This allows for data manipulation before it's used by the application. ```python from typer import Typer from typer_config import use_config, loader_transformer, ConfigDict def uppercase_loader(config: ConfigDict) -> ConfigDict: """Converts all string values in the config to uppercase.""" for key, value in config.items(): if isinstance(value, str): config[key] = value.upper() return config app = Typer() @app.command() @use_config(config_files=["config.yaml"], loader_transformer=uppercase_loader) def main(name: str): """A simple CLI app that uses a custom loader transformation.""" print(f"Hello {name}!") if __name__ == "__main__": app() ``` -------------------------------- ### Python Code Example - Testing Typer CLI with CliRunner Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Shows how to test a Typer CLI application using `typer.testing.CliRunner`. This is essential for verifying the behavior of CLI commands and their interaction with configuration. ```python from typer.testing import CliRunner from your_module import app # Assuming your Typer app is in 'your_module' runner = CliRunner() def test_main_with_config(): # Create a dummy config file with open("config.yaml", "w") as f: f.write("name: TestUser\nage: 30\n") result = runner.invoke(app, ["--config-file", "config.yaml"]) assert result.exit_code == 0 assert "Hello TestUser, you are 30 years old." in result.stdout # Clean up the dummy config file import os os.remove("config.yaml") ``` -------------------------------- ### Python Code Example - Custom Loader with Section Extraction Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Demonstrates using a custom loader that extracts a specific section from the configuration file and applies transformations. This combines section targeting with data manipulation. ```python from typer import Typer from typer_config import use_config, loader_transformer, ConfigDict, get_dict_section def uppercase_section_loader(config: ConfigDict) -> ConfigDict: """Extracts the 'settings' section and converts its string values to uppercase.""" settings = get_dict_section(config, "settings") if settings: for key, value in settings.items(): if isinstance(value, str): settings[key] = value.upper() return settings app = Typer() @app.command() @use_config(config_files=["config.yaml"], loader_transformer=uppercase_section_loader) def main(setting1: str, setting2: int): """A simple CLI app that uses a custom loader for a specific section.""" print(f"Setting 1: {setting1}") print(f"Setting 2: {setting2}") if __name__ == "__main__": app() ``` -------------------------------- ### Typer App with Dotenv Configuration Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/dotenv.md This Python script defines a Typer application that uses the `use_dotenv_config` decorator to load configuration from a .env file. It requires `typer` and `typer_config` to be installed. ```python from typing_extensions import Annotated import typer from typer_config.decorators import use_dotenv_config app = typer.Typer() @app.command() @use_dotenv_config() def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Handle List Arguments in Config Source: https://github.com/maxb2/typer-config/blob/main/docs/known_issues.md Use `argument_list_callback` for list arguments when providing values via a config file. This example demonstrates setting up a Typer application with a list argument that accepts values from a YAML configuration. ```python from typing import List import typer from typer_config import use_yaml_config from typer_config.callbacks import argument_list_callback app = typer.Typer() @app.command() @use_yaml_config() def main( name: str, nicknames: List[str] = typer.Argument(default=None, callback=argument_list_callback), greeting: str = typer.Option(...), suffix: str = typer.Option("!"), ): typer.echo(f"{greeting}, {name}{suffix}") typer.echo(f"{nicknames}") if __name__ == "__main__": app() ``` -------------------------------- ### Typer App with YAML Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/simple_yaml.md This Python script defines a Typer application that uses the `use_yaml_config` decorator to load configuration from a YAML file. It requires `typer` and `typer-config` to be installed. ```python from typing_extensions import Annotated import typer from typer_config.decorators import use_yaml_config # other formats available (1) app = typer.Typer() @app.command() @use_yaml_config() def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Typer App with Schema Validation Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/schema.md This Python script defines a Typer application that loads configuration from a YAML file. It uses the 'schema' library to validate the loaded configuration against a predefined schema before the application logic executes. Ensure the 'schema' and 'typer-config' libraries are installed. ```python from typing import Any from typing_extensions import Annotated from schema import Schema import typer from typer_config import yaml_loader, conf_callback_factory, use_config schema = Schema({"name": str, "greeting": str, "suffix": str}) def validator_loader(param_value: str) -> dict[str, Any]: conf = yaml_loader(param_value) conf = schema.validate(conf) # raises an exception if not valid return conf validator_callback = conf_callback_factory(validator_loader) app = typer.Typer() @app.command() @use_config(validator_callback) def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Running the App with Default Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/fallback_config.md Demonstrates the application's output when only the default configuration file is available. The output reflects the values from 'default.yml'. ```bash $ python simple_app.py Hello, World! $ python simple_app.py --greeting Hi Hi, World! ``` -------------------------------- ### Running the Application with Command-Line Arguments Source: https://github.com/maxb2/typer-config/blob/main/docs/known_issues.md This command shows how to provide arguments directly on the command line, overriding or supplementing values from the configuration file. The list argument accepts multiple values separated by spaces. ```bash $ python arg_list.py Friend Buddy Pal Mate --config config.yml Hello, Friend! ['Buddy', 'Pal', 'Mate'] ``` -------------------------------- ### Running the App with Local Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/fallback_config.md Shows the application's output when a local configuration file ('local.yml') exists. The output uses values from 'local.yml', demonstrating its priority. ```bash $ python simple_app.py Hey, Team!! ``` -------------------------------- ### Running the App with --config Option Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/fallback_config.md Illustrates how the `--config` option overrides all fallback and local configurations. The output reflects values from the specified override configuration file. ```bash $ python simple_app.py --config override.yml Yo, Boss!!! ``` -------------------------------- ### Invoking the Typer App with Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/dotenv.md These bash commands demonstrate how to run the Typer application, specifying the configuration file using the `--config` option and overriding or providing arguments as needed. ```bash $ python simple_app.py --config config.env Hello, World! ``` ```bash $ python simple_app.py --config config.env Alice Hello, Alice! ``` ```bash $ python simple_app.py --config config.env --greeting Hi Hi, World! ``` -------------------------------- ### Running the Application with Config Source: https://github.com/maxb2/typer-config/blob/main/docs/known_issues.md Execute the Python script with the `--config` option pointing to your YAML configuration file. This demonstrates how the application loads values from the config. ```bash $ python arg_list.py --config config.yml Hello, World! ['Globe', 'Earth', 'Terra'] ``` -------------------------------- ### Configuration File (.env) Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/dotenv.md This .env file provides key-value pairs for application configuration, which can be loaded by `typer-config`. Ensure the keys match the application's expected parameters. ```dotenv name=World greeting=Hello suffix=! ``` -------------------------------- ### Handling Missing Configuration Files Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/inheritance_config.md Configure the application to gracefully skip missing configuration files, allowing for optional override locations. ```python @app.command() @use_multifile_config(default_files=[ "/etc/myapp/config.yml", # system defaults (may not exist) "~/.config/myapp/config.yml", # user config (may not exist) "./config.yml", # local config (may not exist) ]) def main(...): ... ``` -------------------------------- ### Invoking Typer App with INI Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/ini.md These bash commands demonstrate how to run the Typer application using an INI configuration file. The `--config` option specifies the path to the configuration file. ```bash $ python simple_app.py --config config.ini Hello, World! ``` ```bash $ python simple_app.py --config config.ini Alice Hello, Alice! ``` ```bash $ python simple_app.py --config config.ini --greeting Hi Hi, World! ``` -------------------------------- ### Invoking Typer App with YAML Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/simple_yaml.md These bash commands demonstrate how to run the Typer application using a YAML configuration file. The `--config` option specifies the path to the configuration file. ```bash $ python simple_app.py --config config.yml Hello, World! $ python simple_app.py --config config.yml Alice Hello, Alice! $ python simple_app.py --config config.yml --greeting Hi Hi, World! ``` -------------------------------- ### Invoke Typer App and View Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/save_config.md Execute the Typer application from the terminal with specified arguments and verify the contents of the generated configuration file. ```bash $ python simple_app.py --greeting Hello --suffix "!" World Hello, World! $ cat ./dumped.json {"name": "World", "greeting": "Hello", "suffix": "!"} ``` -------------------------------- ### Invoking the Typer App Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/inheritance_config.md Demonstrates how to invoke the Typer application from the terminal, showing the effect of configuration inheritance and command-line overrides. ```bash $ python simple_app.py Hey, World! $ python simple_app.py --suffix "!!" Hey, World!! $ python simple_app.py Alice Hey, Alice! ``` -------------------------------- ### Invoking the Typer App Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/schema.md These bash commands demonstrate how to invoke the Typer application with a configuration file. The `--config` option specifies the path to the YAML configuration file. You can also override options directly on the command line. ```bash $ python simple_app.py --config config.yml Hello, World! ``` ```bash $ python simple_app.py --config config.yml Alice Hello, Alice! ``` ```bash $ python simple_app.py --config config.yml --greeting Hi Hi, World! ``` -------------------------------- ### Local Configuration File Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/fallback_config.md A local YAML configuration file that takes precedence over the default configuration. This file overrides 'name', 'greeting', and 'suffix'. ```yaml name: Team greeting: Hey suffix: "!!" ``` -------------------------------- ### YAML Configuration File Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/simple_yaml.md This YAML file provides configuration values for the Typer application, including name, greeting, and suffix. These values can be overridden by command-line arguments. ```yaml name: World greeting: Hello suffix: "!" ``` -------------------------------- ### Format Code Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Applies code formatting using isort for import sorting and black for general code style. Ensures consistent code appearance across the project. ```bash make fmt ``` -------------------------------- ### Typer App with Multifile Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/inheritance_config.md Define a Typer application that uses multifile configuration. Specify default configuration files that will be loaded and merged. ```python from typing_extensions import Annotated import typer from typer_config.decorators import use_multifile_config app = typer.Typer() @app.command() @use_multifile_config(default_files=["base_config.yml", "local_config.yml"]) def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### YAML Configuration for List Arguments Source: https://github.com/maxb2/typer-config/blob/main/docs/known_issues.md This YAML file provides configuration values for the Typer application, including a list of nicknames. Ensure the keys match the argument names in your Python script. ```yaml # config.yml greeting: "Hello" suffix: "!" name: "World" nicknames: ["Globe", "Earth", "Terra"] ``` -------------------------------- ### Test Typer App with Config Dumping Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/save_config.md Use Typer's testing utilities to invoke the application, assert the output, and verify the contents of the saved configuration file. ```python from typer.testing import CliRunner import json, os RUNNER = CliRunner() result = RUNNER.invoke(app, ["--greeting", "Hello", "--suffix", "!", "World"]) assert result.exit_code == 0, "Application failed" assert result.stdout.strip() == "Hello, World!", "Unexpected output" assert os.path.isfile("./dumped.json"), "Saved file does not exist" with open("./dumped.json", "r") as f: assert json.load(f) == { "greeting": "Hello", "suffix": "!", "name": "World", }, "Saved file has wrong contents" ``` -------------------------------- ### Typer App with YAML Config Callback Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/explicit_config.md This Python script defines a Typer application that accepts a `--config` option to load settings from a YAML file. Ensure `is_eager=True` is set for the config parameter to guarantee it's processed first. ```python from typing_extensions import Annotated import typer from typer_config.callbacks import yaml_conf_callback # other formats available (1) app = typer.Typer() @app.command() def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", config: Annotated[ str, typer.Option( callback=yaml_conf_callback, is_eager=True, # THIS IS REALLY IMPORTANT (2) ), ] = "", ): # possibly do something with config typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Override Configuration File Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/fallback_config.md A YAML configuration file used to demonstrate the `--config` option, which always takes the highest priority. This file overrides all other configuration sources. ```yaml name: Boss greeting: Yo suffix: "!!!" ``` -------------------------------- ### Typer App Testing with CliRunner Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/fallback_config.md Contains tests for the Typer application using `CliRunner` to simulate command-line interactions and verify configuration loading behavior. ```python from typer.testing import CliRunner RUNNER = CliRunner() result = RUNNER.invoke(app) assert result.exit_code == 0, f"Loading failed\n\n{result.stdout}" # local.yml exists and takes priority assert result.stdout.strip() == "Hey, Team!!", f"Unexpected output: {result.stdout}" result = RUNNER.invoke(app, ["--greeting", "Hi"]) assert result.exit_code == 0, f"Loading failed\n\n{result.stdout}" assert result.stdout.strip() == "Hi, Team!!", f"Unexpected output: {result.stdout}" result = RUNNER.invoke(app, ["--config", "override.yml"]) assert result.exit_code == 0, f"Loading failed\n\n{result.stdout}" assert result.stdout.strip() == "Yo, Boss!!!", f"Unexpected output: {result.stdout}" ``` -------------------------------- ### Typer App with Default YAML Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/default_config.md This Python script defines a Typer application that uses `@use_yaml_config` to load settings from 'config.yml' by default. Ensure the YAML file is in the same directory or specify a different default path. ```python from typing_extensions import Annotated import typer from typer_config.decorators import use_yaml_config # other formats available (1) app = typer.Typer() @app.command() @use_yaml_config(default_value="config.yml") def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Testing Typer App with YAML Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/simple_yaml.md This Python script uses `typer.testing.CliRunner` to test the Typer application with a YAML configuration file. It verifies that the application loads the configuration correctly and produces the expected output. ```python from typer.testing import CliRunner RUNNER = CliRunner() conf = "config.yml" result = RUNNER.invoke(app, ["--config", conf]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hello, World!", f"Unexpected output for {conf}" result = RUNNER.invoke(app, ["--config", conf, "Alice"]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hello, Alice!", f"Unexpected output for {conf}" result = RUNNER.invoke(app, ["--config", conf, "--greeting", "Hi"]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hi, World!", f"Unexpected output for {conf}" ``` -------------------------------- ### Define pyproject.toml structure Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/pyproject.md This TOML file defines the structure for tool-specific parameters within the `pyproject.toml`. ```toml [tool.my_tool.parameters] name = "World" greeting = "Hello" suffix = "!" ``` -------------------------------- ### Run a Single Test Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Executes a specific test case within the test suite. Useful for debugging or focusing on a particular test. ```bash uv run --all-extras pytest tests/test_example.py::test_name -v ``` -------------------------------- ### Typer App with INI Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/ini.md This Python script defines a Typer application that accepts configuration from an INI file. It uses the `use_ini_config` decorator to load settings from a specified section. ```python from typing_extensions import Annotated import typer from typer_config.decorators import use_ini_config app = typer.Typer() @app.command() @use_ini_config(["section"]) def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### INI Configuration File Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/ini.md This INI file contains configuration settings for the Typer application. The `[section]` header corresponds to the section name specified in the `use_ini_config` decorator. ```ini [section] name = World greeting = Hello suffix = ! ``` -------------------------------- ### Run Tests with Coverage Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Executes all tests using pytest and generates a coverage report in XML format. This command is useful for assessing code coverage. ```bash make test ``` ```bash uv run --all-extras pytest --cov=typer_config --cov-report=xml ``` -------------------------------- ### Testing Typer App with Configuration Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/schema.md This Python code uses Typer's CliRunner to test the application's behavior with different configurations and command-line arguments. It asserts that the exit code is 0 and the output matches the expected string for each test case. ```python from typer.testing import CliRunner RUNNER = CliRunner() conf = "config.yml" result = RUNNER.invoke(app, ["--config", conf]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hello, World!", f"Unexpected output for {conf}" result = RUNNER.invoke(app, ["--config", conf, "Alice"]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hello, Alice!", f"Unexpected output for {conf}" result = RUNNER.invoke(app, ["--config", conf, "--greeting", "Hi"]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hi, World!", f"Unexpected output for {conf}" ``` -------------------------------- ### Alternative loader using loader_transformer Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/pyproject.md This Python code shows an alternative way to define the `pyproject.toml` loader using the `loader_transformer` combinator for a more concise definition. It achieves the same result as the manual loader function. ```python from typing import Any, Dict from typing_extensions import Annotated import typer from typer_config import conf_callback_factory from typer_config.loaders import toml_loader from typer_config.decorators import use_config from typer_config.loaders import loader_transformer pyproject_loader = loader_transformer( toml_loader, param_transformer=lambda param: param or "pyproject.toml", config_transformer=lambda config: config["tool"]["my_tool"]["parameters"], ) pyproject_callback = conf_callback_factory(pyproject_loader) app = typer.Typer() @app.command() @use_config(pyproject_callback) def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Implement custom pyproject.toml loader Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/pyproject.md This Python code defines a custom loader function for typer-config to read parameters from `pyproject.toml`. It handles default file paths and extracts configuration from the specified TOML section. Requires `typer`, `typer-extensions`, and `typer-config`. ```python from typing import Any, Dict from typing_extensions import Annotated import typer from typer_config import conf_callback_factory from typer_config.loaders import toml_loader from typer_config.decorators import use_config def pyproject_loader(param_value: str) -> Dict[str, Any]: if not param_value: # set a default path to read from param_value = "pyproject.toml" pyproject = toml_loader(param_value) conf = pyproject["tool"]["my_tool"]["parameters"] return conf pyproject_callback = conf_callback_factory(pyproject_loader) app = typer.Typer() @app.command() @use_config(pyproject_callback) def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Typer App Testing with INI Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/ini.md This Python code uses Typer's `CliRunner` to test the application's behavior with an INI configuration file. It asserts that the exit code is 0 and the output matches the expected values for different scenarios. ```python from typer.testing import CliRunner RUNNER = CliRunner() conf = "config.ini" result = RUNNER.invoke(app, ["--config", conf]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hello, World!", f"Unexpected output for {conf}" result = RUNNER.invoke(app, ["--config", conf, "Alice"]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hello, Alice!", f"Unexpected output for {conf}" result = RUNNER.invoke(app, ["--config", conf, "--greeting", "Hi"]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hi, World!", f"Unexpected output for {conf}" ``` -------------------------------- ### Local Configuration Override Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/inheritance_config.md A local configuration file used to override specific settings from the base configuration. ```yaml greeting: Hey ``` -------------------------------- ### Testing Typer App with Dotenv Configuration Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/dotenv.md This Python script uses `typer.testing.CliRunner` to programmatically invoke the Typer application and assert its output. It tests various scenarios including default loading, argument overriding, and parameter passing. ```python from typer.testing import CliRunner RUNNER = CliRunner() conf = "config.env" result = RUNNER.invoke(app, ["--config", conf]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hello, World!", f"Unexpected output for {conf}" result = RUNNER.invoke(app, ["--config", conf, "Alice"]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hello, Alice!", f"Unexpected output for {conf}" result = RUNNER.invoke(app, ["--config", conf, "--greeting", "Hi"]) assert result.exit_code == 0, f"Loading failed for {conf}\n\n{result.stdout}" assert result.stdout.strip() == "Hi, World!", f"Unexpected output for {conf}" ``` -------------------------------- ### Typer App with Fallback Config Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/fallback_config.md Defines a Typer application that uses fallback configuration files. The `use_fallback_config` decorator specifies a list of files to check in order. ```python from typing_extensions import Annotated import typer from typer_config.decorators import use_fallback_config app = typer.Typer() @app.command() @use_fallback_config(fallback_files=["local.yml", "default.yml"]) def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Lint and Type-Check Code Source: https://github.com/maxb2/typer-config/blob/main/CLAUDE.md Performs comprehensive code quality checks, including linting with Ruff and type checking with ty. The 'check' command runs both, while 'ruff' and 'check-types' can be run independently. ```bash make check ``` ```bash make ruff ``` ```bash make check-types ``` -------------------------------- ### Use eager config parameter in Typer Source: https://github.com/maxb2/typer-config/blob/main/docs/how.md When using the 'config' parameter directly in your Typer function, set `is_eager=True` to ensure it is processed before other options. This prevents unpredictable parameter value assignments. ```python config: str = typer.Option("", is_eager=True, callback=...) ``` -------------------------------- ### Typer App with Config Dumping Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/save_config.md Define a Typer application with commands that automatically save their parameters to a JSON configuration file using the @dump_json_config decorator. Ensure @use_json_config is placed before @dump_json_config to prevent cascading config file issues. ```python from typing_extensions import Annotated import typer from typer_config.decorators import ( dump_json_config, # other formats available (1) use_json_config, ) app = typer.Typer() @app.command() @use_json_config() # before dump decorator (2) @dump_json_config("./dumped.json") def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` -------------------------------- ### Testing Typer App Invocation Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/inheritance_config.md Unit tests for the Typer application, verifying its behavior with different command-line arguments and configuration settings. ```python from typer.testing import CliRunner RUNNER = CliRunner() result = RUNNER.invoke(app) assert result.exit_code == 0, f"Loading failed\n\n{result.stdout}" assert result.stdout.strip() == "Hey, World!", f"Unexpected output: {result.stdout}" result = RUNNER.invoke(app, ["--suffix", "!!"]) assert result.exit_code == 0, f"Loading failed\n\n{result.stdout}" assert result.stdout.strip() == "Hey, World!!", f"Unexpected output: {result.stdout}" result = RUNNER.invoke(app, ["Alice"]) assert result.exit_code == 0, f"Loading failed\n\n{result.stdout}" assert result.stdout.strip() == "Hey, Alice!", f"Unexpected output: {result.stdout}" ``` -------------------------------- ### Define Pydantic Model and Validator Loader Source: https://github.com/maxb2/typer-config/blob/main/docs/examples/pydantic.md Define the expected configuration structure using a Pydantic BaseModel and create a custom loader function that validates the loaded YAML against this model. This ensures that the configuration adheres to the defined schema. ```python from typing import Any from typing_extensions import Annotated from pydantic import BaseModel import typer from typer_config.loaders import yaml_loader from typer_config.callbacks import conf_callback_factory from typer_config.decorators import use_config class AppConfig(BaseModel): name: str greeting: str suffix: str def validator_loader(param_value: str) -> dict[str, Any]: conf = yaml_loader(param_value) AppConfig.model_validate(conf) # raises an exception if not valid return conf validator_callback = conf_callback_factory(validator_loader) app = typer.Typer() @app.command() @use_config(validator_callback) def main( name: str, greeting: Annotated[str, typer.Option()], suffix: Annotated[str, typer.Option()] = "!", ): typer.echo(f"{greeting}, {name}{suffix}") if __name__ == "__main__": app() ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.