Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/alex-ber/AlexBerUtils/llms.txt

Use this file to discover all available pages before exploring further.

The deploys module (alexber.utils.deploys) provides utilities for use in deployment scripts. It covers two areas: building ZIP archives from directory trees, and loading YAML configuration files with profile merging. The environment variable path utilities (fix_env, fix_retry_env, FixRelCwd, GuardedWorkerException) live in alexber.utils.mains but are frequently used together with deploys in deployment scripts, so they are documented here for convenience.

Installation

# YAML-based utilities (load_config) require the yml extra
pip install alex-ber-utils[yml]
Path-splitting and ZIP utilities have no extra dependencies beyond the standard library.

ZIP archive utilities

split_path(filename, split_dirname)

Splits a file path into two parts at the last occurrence of split_dirname.
from alexber.utils.deploys import split_path

first, second = split_path("/home/user/project/src/module/file.py", "src")
print(first)   # /home/user/project/src
print(second)  # module/file.py
first ends with split_dirname; second starts immediately after it. The concatenation first / second reproduces the original absolute path.
filename
str | Path
required
Path to the file. May be relative or absolute; it is resolved to an absolute path internally.
split_dirname
str | Path
required
Directory name within filename to split on. Must not be None. When split_dirname appears more than once in the path the last occurrence is used.
Returns (Path, Path)(first_part, second_part). Raises FileNotFoundError if split_dirname is None or is not found in filename.

add_to_zip_copy_function(split_dirname, zf)

Factory that returns a closure compatible with the copy_function parameter of shutil.copytree(). Use it to write a directory tree directly into a ZIP archive during a copy operation.
import shutil
import zipfile
from alexber.utils.deploys import add_to_zip_copy_function

with zipfile.ZipFile("release.zip", "w", zipfile.ZIP_DEFLATED) as zf:
    copy_fn = add_to_zip_copy_function(split_dirname="src", zf=zf)
    shutil.copytree(
        src="/home/user/project/src",
        dst="/ignored",           # dst is not used by the closure
        copy_function=copy_fn,
        dirs_exist_ok=True,
    )
Each file is stored in the archive under a path rooted at split_dirname, so the archive entry for /home/user/project/src/module/file.py becomes src/module/file.py.
split_dirname
str | Path
required
The directory name used as the archive root (passed to split_path internally).
zf
zipfile.ZipFile
required
An open, writable ZipFile instance.
Returns a (src, dst) -> None callable suitable for shutil.copytree(copy_function=...).
1

Open the output ZIP file

import zipfile
zf = zipfile.ZipFile("dist/app.zip", "w", zipfile.ZIP_DEFLATED)
2

Create the copy function

from alexber.utils.deploys import add_to_zip_copy_function
copy_fn = add_to_zip_copy_function(split_dirname="app", zf=zf)
3

Copy the directory tree into the archive

import shutil
shutil.copytree(
    src="/workspace/app",
    dst="/tmp/ignored",
    copy_function=copy_fn,
    dirs_exist_ok=True,
)
4

Close the archive

zf.close()

YAML configuration loading

load_config(argumentParser=None, args=None)

Parses a YAML configuration file and merges command-line profile overrides into it. This is a simplified alternative to alexber.utils.init_app_conf.parse_config().
from alexber.utils.deploys import load_config

full_path, config = load_config()
# full_path: pathlib.Path to the resolved config file
# config:    dict with merged profile settings
argumentParser
ArgumentParser | None
default:"None"
A pre-configured argparse.ArgumentParser instance. If None, a default parser is constructed internally.
args
list[str] | None
default:"None"
Argument list to parse. If None, sys.argv is used.
Returns (pathlib.Path, dict) — the resolved path to the configuration file and the merged configuration dictionary. Raises ValueError if ymlparsers.HiYaPyCo.jinja2ctx is None (the YAML parsing context has not been initialised).
load_config depends on alexber.utils.ymlparsers, which is installed via pip install alex-ber-utils[yml]. Profile values supplied on the command line take precedence over defaults in the YAML file.

Environment variable path utilities

These utilities fix os.environ entries that contain file system paths, making deployment scripts work correctly regardless of where a package is installed or which operating system is used.

fix_env(**kwargs)

Prepends the absolute installation prefix of a given package to each path listed in one or more environment variables.
from alexber.utils.mains import fix_env

fix_env(
    ENV_KEYS="PYTHONPATH,DATA_DIR",  # comma-separated env var names
    ENV_MAIN_PCK="myapp",           # package whose location is the prefix
)
ENV_KEYS
str
required
Comma-separated names of os.environ keys to update.
ENV_MAIN_PCK
str
required
Python package name used to determine the absolute path prefix. The function resolves the location of ENV_MAIN_PCK/__init__.py and uses its parent’s parent as the prefix.
ENV_KEY_SEP
str
default:","
Separator used to split ENV_KEYS.
ENV_SEP
str
default:"os.path.sep"
Path separator used inside each path value.
ENV_DELIM_SEP
str
default:"os.pathsep"
Delimiter used between multiple paths within a single environment variable (e.g. ; on Windows, : on Unix).
cls
type | str
default:"OsEnvrionPathExpender"
Implementation class (or its importable dotted string). Override to customise the path-expansion logic.

fix_retry_env(**kwargs)

Makes path values in environment variables work on both Windows and Linux by stripping the Windows drive prefix (e.g. C:\) when the path does not exist as-is on the current OS.
from alexber.utils.mains import fix_retry_env

fix_retry_env(ENV_KEYS="SOME_PATH")
ENV_KEYS
str
required
Comma-separated environment variable names to process.
ENV_KEY_SEP
str
default:","
Separator used to split ENV_KEYS.
ENV_SEP
str
default:"os.path.sep"
Path separator used inside each path value.
ENV_DELIM_SEP
str
default:"os.pathsep"
Delimiter between multiple paths within a single environment variable.
cls
type | str
default:"OsEnvrionPathRetry"
Implementation class or dotted import string.

Context managers

FixRelCwd(relPackage, logger=None)

Temporarily changes the working directory to the directory where relPackage is installed, then restores it on exit. Useful when a package relies on relative paths to locate configuration or resource files.
import mypackage
from alexber.utils.mains import FixRelCwd

with FixRelCwd(mypackage):
    # cwd is now the directory containing mypackage/__init__.py
    config = open("config.yaml").read()
relPackage
module
required
An imported Python module. Its __file__ attribute is used to resolve the target directory.
logger
logging.Logger | None
default:"None"
Logger for debug messages. If None, the module-level logger is used.

GuardedWorkerException(logger=None, suppress=False, default_exc_message="Worker failed")

Surrounds worker-process code with exception handling to prevent multiprocessing.Pool.join() from hanging indefinitely when a worker raises an unpicklable exception.
from alexber.utils.mains import GuardedWorkerException

def worker_task(data):
    with GuardedWorkerException(logger=logger):
        result = heavy_computation(data)
        return result
logger
logging.Logger | None
default:"None"
Logger to record the caught exception. If None, the traceback is printed to sys.stderr.
suppress
bool
default:"False"
If True, swallow the exception after logging. If False (default), re-raise as a plain Exception(default_exc_message).
default_exc_message
str
default:"Worker failed"
Message for the replacement exception when suppress=False.
Without GuardedWorkerException (or equivalent), an unpicklable exception in a worker can cause pool.join() to block forever, leaking memory. Always wrap worker bodies that may raise complex exceptions.

Build docs developers (and LLMs) love