API¶
Code Docstrings¶
Actions¶
Prune YAML¶
Provides functions for ‘pruning’ yaml of extra and empty fields.
- brassy.actions.prune_yaml.direct_pruning_of_files(input_files_or_folders, console, working_dir)[source]¶
Prune empty values from YAML files specified by input paths.
- Parameters:
input_files_or_folders (list of str) – A list of file paths or directories containing YAML files to prune.
console (Console) – An object used for printing messages to the console.
working_dir (str) – The working directory path.
- Return type:
None
Notes
This function collects YAML files from the specified input paths and prunes each file using prune_yaml_file.
Examples
>>> direct_pruning_of_files(['configs/'], console, '/home/user') Pruned configs/config1.yaml Pruned configs/config2.yaml
- brassy.actions.prune_yaml.prune_empty(data, prune_lists=True, key='')[source]¶
Recursively remove empty values from a nested dictionary or list.
- Parameters:
data (dict or list) – The data structure to prune.
prune_lists (bool, optional) – Indicates whether to prune empty lists. Currently unused.
key (str, optional) – The key associated with the current data item, used for special cases.
- Returns:
The pruned data structure, or None if it is empty.
- Return type:
dict or list or None
Notes
The function considers the following values as empty: None, empty strings, empty dictionaries, and empty lists. If a value is 0 and the key is “number”, it is also considered empty to address the related issues field which was previously set to 0 instead of null.
Examples
>>> data = {'a': None, 'b': '', 'c': {'d': [], 'e': 'value'}} >>> prune_empty(data) {'c': {'e': 'value'}}
- brassy.actions.prune_yaml.prune_yaml_file(yaml_file_path, console)[source]¶
Prune empty values from a YAML file and overwrite it with the pruned content.
- Parameters:
yaml_file_path (str) – The file path to the YAML file to be pruned.
console (Console) – An object used for printing messages to the console.
- Return type:
None
Notes
This function reads the YAML file, prunes empty values using prune_empty, and writes the pruned content back to the same file.
Examples
>>> prune_yaml_file('config.yaml', console) Pruned config.yaml
Build Release Notes¶
Build release note output.
- brassy.actions.build_release_notes.build_release_notes(input_files_or_folders, console, rich_open, version=None, release_date=None, header_file=None, footer_file=None, working_dir='.')[source]¶
Build release notes by reading YAML files and templates.
- Parameters:
input_files_or_folders (list of str) – CLI-supplied file or directory paths.
console (Console) – Console for user feedback.
rich_open (Callable) – Context manager factory for reading files.
version (str or None, optional) – Release version string.
release_date (str or None, optional) – Release date override in ISO format.
header_file (str or None, optional) – Path to an optional header file.
footer_file (str or None, optional) – Path to an optional footer file.
working_dir (str, optional) – Base directory for relative paths.
- Returns:
Rendered release notes in RST.
- Return type:
str
- brassy.actions.build_release_notes.find_duplicate_titles(data)[source]¶
Detect duplicate titles across changelog entries.
- Parameters:
data (dict) – Mapping of categories to lists of changelog entries.
- Returns:
True if any title occurs more than once.
- Return type:
bool
- brassy.actions.build_release_notes.format_files_changed_entry(detailed, entry)[source]¶
Format an RST block describing changed files for an entry.
- Parameters:
detailed (bool) – Unused flag kept for compatibility.
entry (dict) – Changelog entry containing file changes.
- Returns:
RST formatted file change listing.
- Return type:
str
- brassy.actions.build_release_notes.format_release_notes(data, version, release_date=None, header=None, footer=None)[source]¶
Generate release notes content from parsed changelog data.
- Parameters:
data (dict) – Parsed changelog entries grouped by category.
version (str or None) – Release version string.
release_date (str or None, optional) – Release date override in ISO format. Defaults to today’s date.
header (str or None, optional) – Optional header content.
footer (str or None, optional) – Optional footer content.
- Returns:
Release notes rendered in RST.
- Return type:
str
- brassy.actions.build_release_notes.generate_file_change_section_list_of_strings(entry, line, category, title, description)[source]¶
Create file-specific section lines for a changelog entry.
- Parameters:
entry (dict) – Changelog entry with file change data.
line (str) – Template string for the section line.
category (str) – Entry category name.
title (str) – Resolved entry title.
description (str) – Resolved entry description.
- Returns:
Section lines formatted per file change.
- Return type:
list of str
- brassy.actions.build_release_notes.generate_section_string(section_lines, changelog_entries, release_date, version, footer, header)[source]¶
Render a changelog section from templates and entries.
- Parameters:
section_lines (list of str) – Template lines for the section.
changelog_entries (dict) – Mapping of categories to changelog entries.
release_date (str) – Release date string.
version (str) – Release version string.
footer (str or None) – Footer content appended to templates.
header (str or None) – Header content prepended to templates.
- Returns:
Rendered section content.
- Return type:
str
Read optional header and footer content.
- Parameters:
rich_open (Callable) – Context manager factory for reading files.
header_file (str or None, optional) – Path to header file.
footer_file (str or None, optional) – Path to footer file.
- Returns:
Header and footer content or None when unavailable.
- Return type:
tuple of str or None
Initialize¶
Initialize brassy with config file.
- brassy.actions.init.init()[source]¶
Initialize configuration files for the application.
This function creates site and user configuration files, and optionally a project configuration file based on user input.
- Return type:
None
Examples
>>> init() Do you want to create a project config file? [y/N]: y
Templates¶
Release YAML¶
Release note YAML validation logic.
- class brassy.templates.release_yaml_template.ChangeItem(*, title: Annotated[str | None, MinLen(min_length=1)], description: Annotated[str | None, MinLen(min_length=1)], files: Files, related_issue: RelatedIssue | RelatedInternalIssue | None = None, date: DateRange | None = None)[source]¶
Bases:
BaseModelA model representing a change “item”, or an atomic change.
This class provides a structured way to represent changes with associated metadata such as title, description, affected files, related issues, and date range.
- Parameters:
title (str or None, optional) – The title of the change item. Must be at least 1 character long if provided. Whitespace is stripped.
description (str or None, optional) – A detailed description of the change. Must be at least 1 character long if provided. Whitespace is stripped.
files (Files) – The files affected by this change.
related_issue (RelatedIssue, RelatedInternalIssue, or None, optional) – An issue related to this change. Aliased as “related-issue” in serialized form. Default is None.
date (DateRange or None, optional) – The date range associated with this change. Default is None.
Notes
Empty strings for ‘title’ and ‘description’ are automatically converted to None during validation.
- description: str | None¶
- empty_str_to_none()[source]¶
Convert empty strings to None for ‘title’ and ‘description’ attributes.
This method checks if the ‘title’ or ‘description’ attributes of the object are empty strings and converts them to None if they are.
- Returns:
self (object)
Returns the instance itself to allow for method chaining.
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- title: str | None¶
- class brassy.templates.release_yaml_template.DateRange(*, start: date | None = None, finish: date | None = None)[source]¶
Bases:
BaseModelDate range model for pydantic validation.
- finish: Date | None¶
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- classmethod parse_date(value)[source]¶
Parse and validate date values.
Converts various date formats to a Date object, handling strings, Date objects, and None values.
- Parameters:
value – Input to parse (Date, None, or string)
- Returns:
Date or None
- Return type:
Parsed date or None for empty values
- Raises:
InvalidDateValue – If the value cannot be parsed as a valid date:
- start: Date | None¶
- class brassy.templates.release_yaml_template.Files(*, deleted: List[str] = [], moved: List[str] = [], added: List[str] = [], modified: List[str] = [])[source]¶
Bases:
BaseModelFiles model for validating files impacted in the changelog.
- added: List[str]¶
- deleted: List[str]¶
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- modified: List[str]¶
- moved: List[str]¶
- exception brassy.templates.release_yaml_template.InvalidDateValueError(date_string: str)[source]¶
Bases:
ValueErrorError for invalid date strings.
- class brassy.templates.release_yaml_template.RelatedInternalIssue(*, internal: Annotated[str | None, _PydanticGeneralMetadata(pattern='[A-Za-z]+#\\d+ - .+')] = None)[source]¶
Bases:
BaseModelPydantic class for ‘internal’ or non-public related issue.
- internal: str | None¶
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class brassy.templates.release_yaml_template.RelatedIssue(*, number: int | List[int] | None = None, repo_url: HttpUrl | None = None)[source]¶
Bases:
BaseModelPydantic class for validating related issue (eg. GitHub issue).
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- number: int | List[int] | None¶
- repo_url: HttpUrl | None¶
- class brassy.templates.release_yaml_template.ReleaseNote(root: RootModelRootType = PydanticUndefined)[source]¶
Bases:
RootModel[Dict[str, List[ChangeItem]]]ReleaseNote is a root model for Release Notes.
It contains a dictionary that maps category names to lists of ChangeItems.
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Settings¶
Pydantic models for validating settings files.
- class brassy.templates.settings_template.ReleaseTemplate(*, release_template: list[dict[str, list[str]]] | None = None)[source]¶
Bases:
BaseModelBase pydantic model for release notes.
- class Config[source]¶
Bases:
objectRequired by pydantic for configuration.
- populate_by_name = True¶
- model_config: ClassVar[ConfigDict] = {'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- release_template: list[dict[str, list[str]]] | None¶
- class brassy.templates.settings_template.SettingsTemplate(*, use_color: bool = True, default_yaml_path: Path | None = None, change_categories: list[str] = ['bug fix', 'enhancement', 'deprecation', 'removal', 'performance', 'documentation', 'continuous integration'], default_title: str = 'NO TITLE', default_description: str = 'NO DESCRIPTION', fail_on_empty_dir: bool = True, description_populates_with_pipe: bool = False, valid_fields: list[str] = ['title', 'description', 'files', 'related-issue'], valid_changes: list[str] = ['deleted', 'moved', 'added', 'modified'], enable_experimental_features: bool = False, templates: ReleaseTemplate | None = ReleaseTemplate(release_template=[{'header': ['{prefix_file}', '']}, {'title': ['', 'Version {release_version} ({release_date})', '**************************', '']}, {'summary': [' * *{change_type}*: {title}']}, {'entry': ['', '{change_type}', '===========', '', '{title}', '-------------------------', '', '{description}', '', '::', '', ' {file_change}: {file}']}, {'footer': ['', '{suffix_file}']}]))[source]¶
Bases:
BaseModelPydantic model for settings file.
- change_categories: list[str]¶
- default_description: str¶
- default_title: str¶
- default_yaml_path: pathlib.Path | None¶
- description_populates_with_pipe: bool¶
- enable_experimental_features: bool¶
- fail_on_empty_dir: bool¶
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- templates: ReleaseTemplate | None¶
- use_color: bool¶
- valid_changes: list[str]¶
- valid_fields: list[str]¶
Utils¶
CLI¶
The CLI only portions of brassy.
Brassy can be run without this file, and importing it brassy without it should allow users to call brassy without the CLI
- brassy.utils.CLI.exit_on_invalid_arguments(args, parser, console)[source]¶
Validate the argparse arguments.
This function validates the provided argparse arguments to ensure that the required input files/folders and output file are provided. If arguments are invalid, it prints an error message and exits the program.
- Parameters:
args (argparse.Namespace) – Parsed arguments.
parser (argparse.ArgumentParser) – The ArgumentParser object used to parse the command-line arguments.
- brassy.utils.CLI.get_file_list_from_cli_input(input_files_or_folders, console, working_dir='.')[source]¶
Parse CLI input string into full file paths.
- brassy.utils.CLI.get_parser()[source]¶
Return ArgumentParser for CLI.
- Returns:
argparse.ArgumentParser
- Return type:
The ArgumentParser object with predefined arguments.
- brassy.utils.CLI.get_yaml_files_from_input(input_files_or_folders)[source]¶
Get a list of YAML files from the given input files or folders.
- Parameters:
input_files_or_folders (list) – List of paths to input files or folders.
- Returns:
List of paths to YAML files.
- Return type:
list
- Raises:
ValueError – If a file is not a YAML file or if no YAML files are found in a directory.
git_handler¶
Handle Git-related functionality.
- brassy.utils.git_handler.get_current_git_branch(sanitize=True)[source]¶
Get the current dirs git branch name.
- Parameters:
sanitize (bool, optional) – If True, sanitize branch name as a valid file name before returning.
- Returns:
The name of the current git branch.
- Return type:
str
- brassy.utils.git_handler.get_git_status(repo_path='.')[source]¶
Retrieve the status of files in the specified Git repository.
- Parameters:
repo_path (str, optional) – The path to the Git repository. Defaults to the current directory.
- Returns:
A dictionary with the following keys:
- ’added’: list of str
List of file paths for files that have been added.
- ’modified’: list of str
List of file paths for files that have been modified.
- ’deleted’: list of str
List of file paths for files that have been deleted.
- ’renamed’: list of str
List of file paths for files that have been renamed.
- Return type:
dict
Messages¶
Handle outputs/inputs to the CLI.
- brassy.utils.messages.get_boolean_prompt_function(enable_format=True)[source]¶
Return a function that prompts Y/N and returns True/False.
- brassy.utils.messages.get_rich_opener(no_format=False)[source]¶
Return opener function with or without a rich progress bar.
- Parameters:
no_format (bool, optional) – If True, returns the opener function without any formatting. If False, returns the opener function with formatting. Defaults to False.
- Returns:
function
- Return type:
The opener function for rich progress bar.
- brassy.utils.messages.init_logger(use_rich)[source]¶
Initialize and configure the logger.
- Parameters:
use_rich (bool) – If True, sets up rich logging else use standard stream logging
- Returns:
logger – The configured logger instance
- Return type:
logging.Logger
- brassy.utils.messages.setup_console(no_format=False, quiet=False)[source]¶
Set up and return the console for printing messages.
- Parameters:
no_format (bool, optional) – Whether to disable formatting. Defaults to False.
quiet (bool, optional) – Whether to suppress console output. Defaults to False.
- Returns:
Console
- Return type:
The configured rich console object.
Settings Manager¶
Manages getting and setting settings.
- brassy.utils.settings_manager.create_config_file(config_file)[source]¶
Create a configuration file with default settings.
- Parameters:
config_file (Path) – Path where the configuration file will be created.
- brassy.utils.settings_manager.get_config_files(app_name)[source]¶
Get configuration file paths in increasing precedence.
- Parameters:
app_name (str) – Name of the application.
- Returns:
List of configuration file paths. Site, user, then project.
- Return type:
List[Path]
- brassy.utils.settings_manager.get_git_repo_root(path='.')[source]¶
Find the root directory of the Git repository for a path.
- Parameters:
path (str, optional) – Path inside the repository. Defaults to “.”.
- Returns:
Absolute path to the repository root (the dir that contains .git).
- Return type:
Path
- brassy.utils.settings_manager.get_project_config_file_path(app_name)[source]¶
Return the path to the project’s configuration file.
- Parameters:
app_name (str) – Name of the application.
- Returns:
Path to the project’s configuration file. If the file does not exist locally, the path is resolved relative to the repository root when possible.
- Return type:
Path
- brassy.utils.settings_manager.get_settings(app_name)[source]¶
Return final application settings with file and env overrides.
- Parameters:
app_name (str) – Name of the application.
- Returns:
An instance containing the merged configuration.
- Return type:
- Raises:
ValidationError – If the final settings fail to validate against the model.
- brassy.utils.settings_manager.get_settings_from_config_files(app_name)[source]¶
Retrieve settings from configuration files without env overrides.
- Parameters:
app_name (str) – Name of the application.
- Returns:
Configuration settings merged from files.
- Return type:
dict
- brassy.utils.settings_manager.get_site_config_file_path(app_name)[source]¶
Retrieve the site-wide configuration file path for the app.
- Parameters:
app_name (str) – Name of the application.
- Returns:
Path to the site’s configuration file.
- Return type:
Path
- brassy.utils.settings_manager.get_user_config_file_path(app_name)[source]¶
Retrieve the user-specific configuration file path for the app.
- Parameters:
app_name (str) – Name of the application.
- Returns:
Path to the user’s configuration file.
- Return type:
Path
- brassy.utils.settings_manager.merge_and_validate_config_files(config_files)[source]¶
Merge settings from multiple config files and validate them.
- Parameters:
config_files (list of Path) – Paths to configuration files. Later files override earlier ones.
- Returns:
Merged and validated configuration settings.
- Return type:
dict
- Raises:
ValidationError – If any file’s settings fail to validate against the SettingsTemplate model.
- brassy.utils.settings_manager.override_dict_with_environmental_variables(input_dict)[source]¶
Override dict values with case insensitive environment variables when available.
- Parameters:
input_dict (dict) – Original settings dictionary.
- Returns:
Updated settings dictionary with environment variable overrides.
- Return type:
dict
- brassy.utils.settings_manager.read_config_file(config_file, create_file_if_not_exist=False)[source]¶
Read and parse a YAML configuration file.
- Parameters:
config_file (Path or str) – Path to the configuration file.
create_file_if_not_exist (bool) – Creates file if it doesn’t exist
- Returns:
Parsed configuration settings as a dictionary.
- Return type:
dict
File Handler¶
Handle file system I/O.
- brassy.utils.file_handler.create_blank_template_yaml_file(file_path_arg, console, working_dir='.')[source]¶
Create a blank YAML template file with a predefined structure.
This function generates a YAML file at the specified path with a default template. It handles special characters required for YAML compatibility and writes the file to disk.
- Parameters:
file_path_arg (str) – The file path of the YAML template as passed via the CLI.
console (rich.console.Console) – A Rich Console object used for displaying messages and errors to the user.
working_dir (str, optional) – The working directory path. Defaults to the current directory “.”.
- Raises:
SystemExit – If a Git repo is not found in the current working directory and no file path is provided, the program exits with an error message.
Notes
This function performs a string replacement to insert a “|” due to an issue with YAML’s handling of pipe symbols. For more details, see: https://github.com/yaml/pyyaml/pull/822
- brassy.utils.file_handler.get_yaml_template_path(file_path_arg, working_dir=None)[source]¶
Return path of the YAML template file based on the given file path argument.
- Parameters:
file_path_arg (str) – The file path argument provided by the user.
- Returns:
str
- Return type:
The path of the YAML template file.
- brassy.utils.file_handler.read_yaml_files(input_files, rich_open)[source]¶
Read and parse the given list of YAML files.
- Parameters:
input_files (list) – List of paths to the YAML files.
- Returns:
Parsed content of all YAML files categorized by type of change.
- Return type:
dict
Examples
>>> read_yaml_files(["file1.yaml", "file2.yaml"]) {'bug-fix': [ {'title': 'fixed explosions', 'description': 'This fixed the explosion mechanism'}, {'title': 'fixed cats not being cute', 'description': 'This made the cats WAY cuter'} ] }
- brassy.utils.file_handler.value_error_on_invalid_yaml(content, file_path)[source]¶
Check if the YAML content follows the correct schema.
- Parameters:
content (dict) – Parsed content of the YAML file.
file_path (str) – Path to the YAML file.
- Raises:
ValueError – If the YAML content does not follow the correct schema.
Main Module¶
Wrapper for CLI call and top-level functions.