Automation Tools

Provides the assets that support various project development automation Command Line Interface (CLI) commands exposed by the ‘cli’ module. Implements the logic of all automation tasks.

class ataraxis_automation.automation.NetlifyMigrationResult(token_migrated, site_migrated)

Bases: object

Stores the outcome of migrating the legacy Netlify credentials of a project.

Notes

The token and the site identifier are migrated independently, so a migration frequently moves one of them and leaves the other in place.

site_migrated: bool

Determines whether the site identifier was written to the project’s .netlify-site file.

token_migrated: bool

Determines whether the API token was copied to the shared .netlifyrc file.

class ataraxis_automation.automation.ProjectEnvironment(activate_command, deactivate_command, create_command, create_dry_run_command, create_from_yaml_command, remove_command, install_dependencies_command, update_command, install_project_command, uninstall_project_command, environment_name, environment_directory, environment_yaml_path)

Bases: object

Encapsulates the data used to interface with the project’s mamba environment.

Notes

This class should not be instantiated directly. Instead, use the resolve_project_environment() class method to get an instance of this class.

activate_command: str

Stores the command used to activate the project’s mamba environment.

create_command: str

Stores the command used to generate a minimally-configured mamba environment.

create_dry_run_command: str

Stores the command used to verify that the project’s mamba environment resolves without creating it.

create_from_yaml_command: str | None

Stores the command used to create a new mamba environment from an existing .yml file.

deactivate_command: str

Stores the command used to deactivate any current environment and switch to the base environment.

environment_directory: Path

Stores the path to the project’s mamba environment directory.

environment_exists()

Determines whether the environment can be activated (exists).

Return type:

bool

Returns:

True if the project’s mamba environment exists and can be activated, and False if it does not exist.

Raises:

RuntimeError – If the environment directory carries conda-meta package records, which identify it as a registered environment that the conda activation machinery is nonetheless unable to activate.

environment_name: str

Stores the name of the project’s mamba environment with the appended os-suffix.

environment_yaml_path: Path

Stores the path to the os-specific .yml file that keeps the project’s exported environment specification.

export_environment()

Exports the project’s mamba environment to the os-specific .yml file stored in the project’s ‘envs’ directory.

Return type:

None

Notes

The specification is written to a temporary file inside the target directory and renamed over the destination only after mamba reports a successful export that declares at least one dependency. A failed export therefore leaves the previously exported file intact.

Raises:

RuntimeError – If mamba fails to export the environment or exports a specification that declares no dependencies.

install_dependencies_command: str

Stores the command used to install all project dependencies into the project’s mamba environment using uv.

install_project_command: str

Stores the command used to build and install the project as a library into the project’s mamba environment.

remove_command: str

Stores the command used to remove (delete) the project’s mamba environment.

classmethod resolve_project_environment(project_root, environment_name, python_version='3.13', environment_directory=None, *, prerelease=False)

Generates the mamba and uv commands used to manipulate the project- and os-specific mamba environment and packages them into a ProjectEnvironment instance.

Parameters:
  • project_root (Path) – The absolute path to the root directory of the processed project.

  • environment_name (str) – The base-name of the project’s mamba environment.

  • python_version (str, default: '3.13') – The Python version installed into the mamba environment when the environment is created.

  • environment_directory (Path | None, default: None) – Optional. The absolute path to the directory used by the mamba / conda manager to store Python environments. This argument only needs to be provided if the automatic (default) environment resolution fails.

  • prerelease (bool, default: False) – Determines whether uv is allowed to install prerelease versions of dependencies.

Return type:

ProjectEnvironment

Returns:

The resolved ProjectEnvironment instance.

Raises:
  • RuntimeError – If the host OS is unsupported, mamba or uv is not accessible, or the mamba environments directory cannot be resolved and no manual override is provided.

  • ValueError – If the project name cannot be extracted from pyproject.toml, duplicate dependencies are found, or the pyproject.toml file declares no dependencies at all.

uninstall_project_command: str

Stores the command used to uninstall the project library from the project’s mamba environment.

update_command: str | None

Stores the command used to update an already existing mamba environment using an existing .yml file.

verify_removable()

Verifies that the environment is not the one hosting the interpreter of the running process.

Return type:

None

Notes

Windows holds an open handle on every loaded module, so the files of the environment that provides the running interpreter stay locked for as long as the process lives. Mamba unlinks the packages, renames the files it is unable to delete to ‘.mamba_trash’, and leaves a directory that no longer resolves as an environment. The check runs before the removal starts, which keeps the environment intact.

Raises:

RuntimeError – If the environment provides the interpreter or the conda prefix of the running process.

ataraxis_automation.automation.colorize_message(message, color, *, wrap=True)

Modifies the input string to include an ANSI color code and, if necessary, formats the message by wrapping it at 120 characters.

Parameters:
  • message (str) – The input message string to format and colorize.

  • color (str) – The ANSI color code to use for coloring the message.

  • wrap (bool, default: True) – Determines whether to format the message by wrapping it at 120 characters.

Return type:

str

Returns:

The colorized and wrapped (if requested) message string.

ataraxis_automation.automation.delete_stubs(library_root)

Removes all .pyi stub files from the root library directory and its subdirectories.

Parameters:

library_root (Path) – The absolute path to the root library directory.

Return type:

None

ataraxis_automation.automation.deploy_documentation(documentation_directory, site, token)

Deploys the pre-built API documentation to the target Netlify site.

Packages the documentation directory into a ZIP archive and uploads it to Netlify as a production deployment.

Notes

Netlify deployments are atomic. The uploaded archive has to contain every file served by the site, as each deployment fully replaces the content of the previous one.

Parameters:
  • documentation_directory (Path) – The absolute path to the directory that stores the built documentation .html files.

  • site (str) – The Netlify site identifier. Both the site’s API (UUID) identifier and its domain name are accepted.

  • token (str) – The Netlify API token used to authenticate the deployment request.

Return type:

str

Returns:

The URL of the website that serves the deployed documentation.

Raises:

RuntimeError – If the documentation directory does not contain the ‘index.html’ file. If the deployment request does not reach Netlify or if Netlify rejects the deployment.

ataraxis_automation.automation.derive_netlify_site(project_root)

Derives the Netlify site identifier of the target project from the name of its root directory.

Notes

The derived identifier follows the site naming convention shared by nearly all Ataraxis framework and Sollertia platform projects, and projects that use a different identifier override it with the value stored in their .netlify-site file.

Parameters:

project_root (Path) – The absolute path to the root directory of the processed project.

Return type:

str

Returns:

The derived Netlify site identifier.

ataraxis_automation.automation.format_message(message)

Formats input message strings to follow the general Ataraxis framework style.

Parameters:

message (str) – The input message string to format.

Return type:

str

Returns:

The formatted message string.

ataraxis_automation.automation.generate_typed_marker(library_root)

Crawls the library directory tree and ensures that the py.typed marker exists only at the root level of the directory.

Parameters:

library_root (Path) – The path to the root level of the library directory.

Return type:

None

ataraxis_automation.automation.migrate_legacy_netlifyrc(project_root)

Splits the Netlify credentials stored in the target project’s root directory between the shared application directory and the project’s .netlify-site file.

Notes

Earlier library versions stored both the site identifier and the API token inside a single .netlifyrc file in the root directory of each project. This function preserves both values of a project that still uses that layout, so the user does not have to enter them again.

Parameters:

project_root (Path) – The absolute path to the root directory of the processed project.

Return type:

NetlifyMigrationResult

Returns:

The result of the migration, which reports the token and the site identifier separately, as each is migrated only when its destination is not already configured.

Raises:

configparser.Error – If either .netlifyrc file exists but contains malformed INI syntax.

ataraxis_automation.automation.migrate_legacy_pypirc(project_root)

Copies the PyPI API token stored in the target project’s root directory to the shared application directory.

Notes

Earlier library versions stored the token inside the root directory of each project. This function preserves the token of a project that still uses that layout, so the user does not have to enter it again.

Parameters:

project_root (Path) – The absolute path to the root directory of the processed project.

Return type:

bool

Returns:

True if the token was migrated and False if the shared token is already configured or there is no legacy token to migrate.

Raises:

configparser.Error – If either .pypirc file exists but contains malformed INI syntax.

ataraxis_automation.automation.move_stubs(stubs_directory, library_root)

Moves typing stub (.pyi) files from the ‘stubs’ directory to the appropriate level(s) of the library directory tree.

Notes

The ‘stubs’ directory is expected to hold the output of stubgen, which is exactly one subdirectory with an __init__.pyi file. That subdirectory is considered to be the library root in the ‘stubs’ directory structure.

Parameters:
  • stubs_directory (Path) – The absolute path to the project’s “stubs” directory.

  • library_root (Path) – The absolute path to the root library directory.

Raises:

RuntimeError – If the ‘stubs’ directory does not contain exactly one subdirectory with an __init__.pyi file.

Return type:

None

ataraxis_automation.automation.read_netlify_site(project_root)

Reads the Netlify site identifier stored in the target project’s .netlify-site file.

Parameters:

project_root (Path) – The absolute path to the root directory of the processed project.

Return type:

str | None

Returns:

The stored Netlify site identifier, or None if the file does not exist or stores no identifier.

ataraxis_automation.automation.repair_stale_certificate_variables()

Clears the certificate-bundle environment variables that point to paths which no longer exist.

Notes

The conda-forge openssl package ships activation scripts only for Windows, where they point SSL_CERT_FILE and SSL_CERT_DIR into the active environment. Those scripts assign a variable only when it is unset, so a value left behind by a removed environment survives every later activation. The package managers this library calls then read a bundle that is absent and refuse to trust any certificate, which fails every download.

Each variable is cleared rather than repointed at the active conda prefix, because the environment named by a stale value is usually the one the caller is rebuilding. Clearing it restores the bundled certificate roots of uv and requests. The conda guard variable is cleared alongside the variable it tracks, as the activation scripts skip a variable whose guard remains set.

Return type:

tuple[str, ...]

Returns:

The names of the cleared environment variables, in the order they were evaluated.

ataraxis_automation.automation.resolve_application_directory()

Resolves the path to the directory that stores the API tokens shared by all projects managed on the host-machine.

Notes

The directory is created if it does not already exist.

Return type:

Path

Returns:

The absolute path to the application directory.

ataraxis_automation.automation.resolve_documented_project_directory()

Resolves the current working directory and verifies that it points to an Ataraxis framework project that builds API documentation.

Notes

This verification accepts every project archetype that builds API documentation, including the C++ PlatformIO projects that have no Python package layout.

Return type:

Path

Returns:

The absolute path to the current working directory, if it points to a project that builds API documentation.

Raises:

RuntimeError – If the current working directory does not point to a project that builds API documentation.

ataraxis_automation.automation.resolve_library_root(project_root)

Resolves the absolute path to the project’s root library directory.

Notes

This function relies on the following resolution heuristic: library root is a directory at most one level below /src with an __init__.py file.

Parameters:

project_root (Path) – The absolute path to the root directory of the processed project.

Return type:

Path

Returns:

The absolute path to the root library directory.

Raises:

RuntimeError – If the valid root directory candidate cannot be found based on the determination heuristics.

ataraxis_automation.automation.resolve_netlifyrc_path()

Resolves the path to the .netlifyrc file that stores the Netlify API token shared by all projects managed on the host-machine.

Return type:

Path

Returns:

The absolute path to the .netlifyrc file.

ataraxis_automation.automation.resolve_project_directory()

Resolves the current working directory and verifies that it points to a valid Ataraxis framework project.

Return type:

Path

Returns:

The absolute path to the current working directory, if it points to a valid Ataraxis framework project.

Raises:

RuntimeError – If the current working directory does not point to a valid Ataraxis framework project.

ataraxis_automation.automation.resolve_pypirc_path()

Resolves the path to the .pypirc file that stores the PyPI API token shared by all projects managed on the host-machine.

Return type:

Path

Returns:

The absolute path to the .pypirc file.

ataraxis_automation.automation.robust_rmtree(path)

Removes a directory tree with retry logic to handle transient Windows file locks.

On Windows, antivirus scanners, the Search Indexer, and recently-exited processes can hold file handles briefly after the calling process has finished with them. This function wraps shutil.rmtree() with an onerror handler that clears read-only attributes and an outer retry loop with exponential backoff to tolerate these transient locks. On non-Windows platforms, calls shutil.rmtree() directly with no retry overhead.

Parameters:

path (Path) – The absolute path to the directory tree to remove.

Raises:

OSError – If the directory cannot be removed. On Windows, transient PermissionErrors are retried with exponential backoff before the error is re-raised. On non-Windows platforms and for other error types, the error propagates immediately.

Return type:

None

ataraxis_automation.automation.verify_netlifyrc(file_path)

Verifies that the target .netlifyrc file contains the Netlify authentication credentials (API token).

Notes

This function is not able to verify whether the token is currently active.

Parameters:

file_path (Path) – The absolute path to the .netlifyrc file to verify.

Return type:

bool

Returns:

True if the .netlifyrc file appears to contain a well-configured API token and False otherwise.

Raises:

configparser.Error – If the .netlifyrc file exists but contains malformed INI syntax.

ataraxis_automation.automation.verify_pypirc(file_path)

Verifies that the target .pypirc file contains valid PyPI authentication credentials (API token).

Notes

This function is not able to verify whether the token is currently active.

Parameters:

file_path (Path) – The absolute path to the .pypirc file to verify.

Return type:

bool

Returns:

True if the .pypirc file appears to contain a well-configured API token and False otherwise.

Raises:

configparser.Error – If the .pypirc file exists but contains malformed INI syntax.

ataraxis_automation.automation.write_netlify_site(project_root, site)

Writes the Netlify site identifier to the target project’s .netlify-site file.

Notes

Unlike the API token, the site identifier is not a secret and differs for each project, so the file it is written to is tracked by the project’s version control system.

Parameters:
  • project_root (Path) – The absolute path to the root directory of the processed project.

  • site (str) – The Netlify site identifier to store in the file.

Return type:

None

Command Line Interfaces (CLIs)

automation-cli

Exposes the helper commands used to automate various project development and building steps.

Commands exposed by this interface are intended to be called via the ‘tox’ automation manager and should not be used directly by end-users.

Usage

automation-cli [OPTIONS] COMMAND [ARGS]...

acquire-netlify-token

Ensures that the project’s .netlify-site file contains the Netlify site identifier and that the shared .netlifyrc file contains a validly formatted Netlify API token.

Usage

automation-cli acquire-netlify-token [OPTIONS]

Options

-rt, --replace-token

If this flag is provided, the command replaces the API token stored in the shared .netlifyrc file even if that file already contains a valid token.

-rs, --replace-site

If this flag is provided, the command replaces the site identifier stored in the project’s .netlify-site file even if that file already contains an identifier.

acquire-pypi-token

Ensures that a validly formatted PyPI API token is contained in the .pypirc file stored in the shared application directory.

Usage

automation-cli acquire-pypi-token [OPTIONS]

Options

-rt, --replace-token

If this flag is provided, the command replaces the API token stored in the shared .pypirc file even if that file already contains a valid token.

create-environment

Creates the project’s mamba environment and installs the project dependencies into the created environment.

Usage

automation-cli create-environment [OPTIONS]

Options

-e, --environment-name <environment_name>

Required The name of the project’s mamba environment without the os-suffix, e.g., ‘project_dev’.

-p, --python-version <python_version>

Required The python version to use for the project’s mamba environment, e.g. ‘3.13’.

-ed, --environment-directory <environment_directory>

The absolute path to the local conda / mamba environments directory. This optional argument allows overriding the default environment detection procedure when it fails.

--prerelease

Determines whether uv is allowed to install prerelease versions of dependencies.

deploy-docs

Deploys the API documentation built by the ‘docs’ task to the project’s Netlify site.

Usage

automation-cli deploy-docs [OPTIONS]

export-environment

Exports the requested mamba environment as a .yml file to the /envs directory.

Usage

automation-cli export-environment [OPTIONS]

Options

-e, --environment-name <environment_name>

Required The name of the project’s mamba environment without the os-suffix, e.g., ‘project_dev’.

-ed, --environment-directory <environment_directory>

The absolute path to the local conda / mamba environments directory. This optional argument allows overriding the default environment detection procedure when it fails.

import-environment

Creates or updates the existing project’s mamba environment based on the operating-system-specific .yml file stored in the project /envs directory.

Usage

automation-cli import-environment [OPTIONS]

Options

-e, --environment-name <environment_name>

Required The name of the project’s mamba environment without the os-suffix, e.g., ‘project_dev’.

-ed, --environment-directory <environment_directory>

The absolute path to the local conda / mamba environments directory. This optional argument allows overriding the default environment detection procedure when it fails.

install-project

Builds and installs the project into the specified mamba environment as a library.

Usage

automation-cli install-project [OPTIONS]

Options

-e, --environment-name <environment_name>

Required The name of the project’s mamba environment without the os-suffix, e.g., ‘project_dev’.

-ed, --environment-directory <environment_directory>

The absolute path to the local conda / mamba environments directory. This optional argument allows overriding the default environment detection procedure when it fails.

--prerelease

Determines whether uv is allowed to install prerelease versions of dependencies.

process-stubs

Distributes the stub files from the /stubs directory to the appropriate level of the /src or src/library_name directory (depending on the type of the processed project).

Once all stub files are distributed, removes the /stubs directory.

Usage

automation-cli process-stubs [OPTIONS]

process-typed-markers

Crawls the library root directory and ensures that the ‘py.typed’ marker is found only at the highest level of the library hierarchy (the highest directory with __init__.py in it).

Usage

automation-cli process-typed-markers [OPTIONS]

provision-environment

Recreates the project’s mamba environment and installs the project dependencies into the recreated environment.

Usage

automation-cli provision-environment [OPTIONS]

Options

-e, --environment-name <environment_name>

Required The name of the project’s mamba environment without the os-suffix, e.g., ‘project_dev’.

-p, --python-version <python_version>

Required The python version to use for the project’s mamba environment, e.g. ‘3.13’.

-ed, --environment-directory <environment_directory>

The absolute path to the local conda / mamba environments directory. This optional argument allows overriding the default environment detection procedure when it fails.

--prerelease

Determines whether uv is allowed to install prerelease versions of dependencies.

purge-stubs

Removes all existing stub (.pyi) files from the library source code directories.

Usage

automation-cli purge-stubs [OPTIONS]

remove-environment

Removes (deletes) the project’s mamba environment and its environment directory, if either exists.

Usage

automation-cli remove-environment [OPTIONS]

Options

-e, --environment-name <environment_name>

Required The name of the project’s mamba environment without the os-suffix, e.g., ‘project_dev’.

-ed, --environment-directory <environment_directory>

The absolute path to the local conda / mamba environments directory. This optional argument allows overriding the default environment detection procedure when it fails.

uninstall-project

Uninstalls the project library from the specified mamba environment.

Usage

automation-cli uninstall-project [OPTIONS]

Options

-e, --environment-name <environment_name>

Required The name of the project’s mamba environment without the os-suffix, e.g., ‘project_dev’.

-ed, --environment-directory <environment_directory>

The absolute path to the local conda / mamba environments directory. This optional argument allows overriding the default environment detection procedure when it fails.

upload-project

Uploads the distributions built by the ‘build’ task to PyPI.

This command resolves the PyPI API token from the shared application directory, so the project does not have to store the token in its root directory.

Usage

automation-cli upload-project [OPTIONS]