API Reference

scitex_container

scitex-container: Unified container management for Apptainer and Docker.

scitex_container.build(def_name='scitex-cloud-shared-v0.1.0', output_dir=None, force=False, sandbox=False, *, def_path=None, image_name=None, use_sudo=False, fakeroot=None)[source]

Build Apptainer/Singularity SIF or sandbox from .def file.

Parameters:
  • def_name (str) – Name of the .def file (without extension) when looking it up in the discovered containers dir. Ignored if def_path is given.

  • output_dir (str or Path, optional) – Directory under which the per-image subdir is created (i.e. the artifact lands at <output_dir>/<image_name>/<image_name>.sif). Defaults to the directory containing the resolved .def file.

  • force (bool) – Force rebuild even if .def is unchanged.

  • sandbox (bool) – If True, build a sandbox directory instead of a SIF image. Uses: apptainer build –sandbox –fakeroot output-sandbox/ input.def

  • def_path (str or Path, optional) – Explicit path to the .def file. Lets out-of-tree callers (e.g. scitex-agent-container, whose recipes ship inside its own wheel) bypass find_containers_dir. When given, def_name is ignored for lookup and image_name defaults to the .def’s stem.

  • image_name (str, optional) – Name of the per-image subdir + artifact stem (i.e. the artifact lands at <output_dir>/<image_name>/<image_name>.sif). Defaults to def_name (or the .def stem when def_path is given). Use this when the on-disk recipe is named differently from the image you want to produce — e.g. sac’s apptainer-base.defsac-base/sac-base.sif.

  • use_sudo (bool)

  • fakeroot (bool | None)

Returns:

Path to the built .sif file or sandbox directory.

Return type:

Path

Raises:
scitex_container.cleanup(containers_dir, keep=3)[source]

Remove old scitex-v*.sif files, keeping the N most recent.

Never removes the active version (current.sif target) or any scitex-base-v*.sif base images.

Parameters:
  • containers_dir (Path) – Directory containing SIF files.

  • keep (int) – Number of most-recent versioned SIFs to keep (default: 3).

Returns:

Paths of removed SIF files.

Return type:

list[Path]

scitex_container.deploy(source_dir, target_dir=PosixPath('/opt/scitex/singularity'))[source]

Copy active SIF and base SIF to target directory.

Copies the currently active scitex-v*.sif and the latest scitex-base-v*.sif to target_dir, then recreates the current.sif symlink there. Uses sudo for the copy.

Parameters:
  • source_dir (Path) – Directory containing the built SIF files.

  • target_dir (Path) – Deployment target directory (default: /opt/scitex/singularity).

Raises:
Return type:

None

scitex_container.docker_rebuild(env='dev', project_dir=None)

Rebuild Docker containers without using the cache.

Runs: docker compose -f <compose_file> build --no-cache

Parameters:
  • env (str) – Environment name used to locate the compose file.

  • project_dir (str or Path or None) – Explicit directory containing the compose file. When None, the function walks upward from the current working directory.

Returns:

Exit code of the docker compose command (0 = success).

Return type:

int

scitex_container.docker_restart(env='dev', project_dir=None)

Restart Docker containers (down then up).

Runs: docker compose -f <compose_file> down then: docker compose -f <compose_file> up -d

Parameters:
  • env (str) – Environment name used to locate the compose file.

  • project_dir (str or Path or None) – Explicit directory containing the compose file.

Returns:

Exit code of the final up -d command (0 = success). If down fails its exit code is returned instead.

Return type:

int

scitex_container.env_snapshot(containers_dir=None, dev_repos=None)[source]

Capture a lightweight JSON-serializable environment snapshot.

Gracefully degrades — never raises, just omits fields that cannot be determined.

Parameters:
  • containers_dir (str or Path, optional) – Path to the containers directory. Auto-detected via find_containers_dir() when None.

  • dev_repos (list of str or Path, optional) – Paths to git repositories to include in dev_repos section.

Returns:

JSON-serializable snapshot with keys: schema_version, timestamp, container, host, dev_repos, lock_files.

Return type:

dict

scitex_container.host_check()

Check which host packages are installed.

Returns:

Structured status per package group:

{
    "texlive": {
        "installed": True,
        "version": "pdfTeX 3.141592653...",
        "binaries": ["pdflatex", "bibtex", ...],
    },
    "imagemagick": {
        "installed": True,
        "version": "Version: ImageMagick 6.9...",
        "binaries": ["convert", "identify"],
    },
}

Return type:

dict

scitex_container.host_install(texlive=False, imagemagick=False, all=False, check_only=False)

Install host packages by calling the shell script.

Parameters:
  • texlive (bool) – Install TeXLive packages.

  • imagemagick (bool) – Install ImageMagick.

  • all (bool) – Install all packages (overrides texlive/imagemagick flags).

  • check_only (bool) – Run the script in –check mode without installing anything.

Returns:

Status per package group:

{
    "texlive": {"status": "installed", "returncode": 0},
    "imagemagick": {"status": "skipped", "returncode": None},
    "script": "/abs/path/to/install-host-packages.sh",
}

Return type:

dict

Raises:

FileNotFoundError – If the install script cannot be found.

scitex_container.list_versions(containers_dir)[source]

List all versioned SIFs with metadata.

Parameters:

containers_dir (Path) – Directory containing SIF files.

Returns:

Each dict contains keys: version, path, size, date, active. Sorted by modification time (newest first).

Return type:

list[dict]

scitex_container.rollback(containers_dir, use_sudo=False)[source]

Switch to the version before the current one (by modification time).

Parameters:
  • containers_dir (Path) – Directory containing SIF files.

  • use_sudo (bool) – If True, run symlink commands via sudo.

Returns:

Version string that is now active after rollback.

Return type:

str

Raises:

RuntimeError – If there is no current version or no previous version to roll back to.

scitex_container.sandbox_create(source, containers_dir=None, *, output_dir=None)

Build a sandbox directory from a SIF image or .def file.

Creates a timestamped sandbox (sandbox-YYYYMMDD_HHMMSS/) and updates the current-sandbox symlink to point to it.

Parameters:
  • source (str or Path) – Path to the source .sif file or .def file.

  • containers_dir (str or Path, optional) – Parent directory for sandbox output and symlink. Defaults to source file’s parent directory.

  • output_dir (str or Path, optional) – Explicit output path (overrides timestamped naming).

Returns:

Path to the created sandbox directory.

Return type:

Path

Raises:
scitex_container.status(containers_dir=None)[source]

List available containers and their status.

Parameters:

containers_dir (str or Path, optional) – Directory containing .def files. Auto-detected if not given.

Returns:

List of container info dicts with keys: name, def_path, sif_path, sif_size, sif_date, hash_current, hash_stored, needs_rebuild.

Return type:

list[dict]

scitex_container.switch(version, containers_dir, use_sudo=False)

Atomically switch current.sif symlink to scitex-v{version}.sif.

Uses ln -sf to create a temporary symlink, then mv -Tf for an atomic rename on the same filesystem.

Parameters:
  • version (str) – Target version string (e.g. “2.19.5”).

  • containers_dir (Path) – Directory containing SIF files.

  • use_sudo (bool) – If True, run ln/mv via sudo (needed for /opt/scitex paths).

Raises:
Return type:

None

scitex_container.verify(sif_path, def_path=None, lock_dir=None)[source]

Verify container integrity.

Checks: 1. SIF exists and computes its SHA256 2. If def_path given, compares .def hash against stored .def-hash 3. If lock files exist, runs pip freeze / dpkg-query inside the SIF

and compares against stored lock files

Parameters:
  • sif_path (str or Path) – Path to the .sif file to verify.

  • def_path (str or Path, optional) – Path to the .def file that should have produced this SIF.

  • lock_dir (str or Path, optional) – Directory containing lock files (requirements-lock.txt, dpkg-lock.txt). Defaults to same directory as the SIF.

Returns:

Verification results:

{
    "sif": {"path": "...", "sha256": "...", "exists": True},
    "def_origin": {"status": "pass|fail|skip", "detail": "..."},
    "pip_lock": {"status": "pass|fail|skip", "detail": "...", "diff_count": 0},
    "dpkg_lock": {"status": "pass|fail|skip", "detail": "...", "diff_count": 0},
    "overall": "pass|fail"
}

Return type:

dict

scitex_container.apptainer

Apptainer container management: build, sandbox, versioning, command building.

scitex_container.apptainer.build(def_name='scitex-cloud-shared-v0.1.0', output_dir=None, force=False, sandbox=False, *, def_path=None, image_name=None, use_sudo=False, fakeroot=None)[source]

Build Apptainer/Singularity SIF or sandbox from .def file.

Parameters:
  • def_name (str) – Name of the .def file (without extension) when looking it up in the discovered containers dir. Ignored if def_path is given.

  • output_dir (str or Path, optional) – Directory under which the per-image subdir is created (i.e. the artifact lands at <output_dir>/<image_name>/<image_name>.sif). Defaults to the directory containing the resolved .def file.

  • force (bool) – Force rebuild even if .def is unchanged.

  • sandbox (bool) – If True, build a sandbox directory instead of a SIF image. Uses: apptainer build –sandbox –fakeroot output-sandbox/ input.def

  • def_path (str or Path, optional) – Explicit path to the .def file. Lets out-of-tree callers (e.g. scitex-agent-container, whose recipes ship inside its own wheel) bypass find_containers_dir. When given, def_name is ignored for lookup and image_name defaults to the .def’s stem.

  • image_name (str, optional) – Name of the per-image subdir + artifact stem (i.e. the artifact lands at <output_dir>/<image_name>/<image_name>.sif). Defaults to def_name (or the .def stem when def_path is given). Use this when the on-disk recipe is named differently from the image you want to produce — e.g. sac’s apptainer-base.defsac-base/sac-base.sif.

  • use_sudo (bool)

  • fakeroot (bool | None)

Returns:

Path to the built .sif file or sandbox directory.

Return type:

Path

Raises:
scitex_container.apptainer.build_dev_pythonpath(dev_repos)[source]

Build a PYTHONPATH string that prepends /opt/dev/{name}/src for each dev repo.

Packages in dev repos are assumed to follow the src-layout convention (i.e. repo_root/src/<package>), so we add /opt/dev/{name}/src.

Parameters:

dev_repos (list[dict]) – List of dev repo dicts, each with a name key.

Returns:

Colon-separated PYTHONPATH string, or empty string if no repos.

Return type:

str

scitex_container.apptainer.build_exec_args(container_path, username, host_user_dir, host_project_dir, project_slug, dev_repos=None, host_mounts=None, texlive_prefix='')[source]

Build the apptainer exec argument list.

Handles: - Sandbox vs SIF detection. Both use --writable-tmpfs for user

sessions so each user gets a clean per-session tmpfs overlay.

  • For SIF images, --containall is added to prevent host mounts leaking in.

  • Dev repo bind mounts.

  • PYTHONPATH injection for dev repos (src-layout).

  • Host package bind mounts (TeX Live, etc.).

  • Standard --env, --home, --bind args.

Parameters:
  • container_path (str) – Path to the SIF file or sandbox directory.

  • username (str) – Username for the session (used for home dir and env vars).

  • host_user_dir (Path) – Host path to the user’s home directory.

  • host_project_dir (Path) – Host path to the project directory.

  • project_slug (str) – Project identifier (e.g. “my-project”).

  • dev_repos (list[dict], optional) – Dev repo dicts with name and host_path keys.

  • host_mounts (list[dict], optional) – Generic host mount dicts with host_path, container_path, mode.

  • texlive_prefix (str) – Host prefix for TeX Live (e.g. /usr).

Returns:

Flat list starting with ["apptainer", "exec", ...].

Return type:

list[str]

scitex_container.apptainer.build_host_mount_binds(host_mounts=None, texlive_prefix='')[source]

Build --bind argument pairs for host package mounts.

Parameters:
  • host_mounts (list[dict], optional) – Generic list of {host_path, container_path, mode} dicts.

  • texlive_prefix (str) –

    Host prefix for TeX Live installation (e.g. /usr). When set, auto-generates bind entries for TeX Live share directories and binaries. Example: /usr generates:

    --bind /usr/share/texlive:/usr/share/texlive:ro --bind /usr/share/texmf-dist:/usr/share/texmf-dist:ro --bind /usr/bin/pdflatex:/usr/bin/pdflatex:ro … (all _TEXLIVE_BINS)

Returns:

Flat list of alternating "--bind" / "<spec>" strings ready to be inserted into the apptainer argv list.

Return type:

list[str]

scitex_container.apptainer.build_instance_start_script(container_path, username, host_user_dir, host_project_dir, project_slug, instance_name, dev_repos=None, host_mounts=None, texlive_prefix='')[source]

Build a bash script that starts an apptainer instance and keeps it alive.

This script is designed to be submitted via sbatch. It: 1. Starts an apptainer instance with --writable-tmpfs (shared overlay). 2. Prints INSTANCE_READY on success or INSTANCE_FAILED on failure. 3. Sleeps in a loop while the instance is alive (sbatch keeps the

allocation open).

Parameters:
  • container_path (str) – Path to the SIF file or sandbox directory.

  • username (str) – Username for the session.

  • host_user_dir (Path) – Host path to the user’s home directory.

  • host_project_dir (Path) – Host path to the project directory.

  • project_slug (str) – Project identifier.

  • instance_name (str) – Name for the apptainer instance (e.g. scitex-user-project).

  • dev_repos (list[dict], optional) – Dev repo dicts with name and host_path keys.

  • host_mounts (list[dict], optional) – Generic host mount dicts.

  • texlive_prefix (str) – Host prefix for TeX Live.

Returns:

Complete bash script content.

Return type:

str

scitex_container.apptainer.build_sbatch_command(instance_name, script_path, slurm_partition='compute', slurm_time_limit='8:00:00', slurm_cpus=4, slurm_memory_gb=16, username='', project_slug='')[source]

Build sbatch command to submit an allocation script.

Parameters:
  • instance_name (str) – Used to derive the SLURM job name.

  • script_path (str) – Path to the bash script (from build_instance_start_script).

  • slurm_partition (str) – SLURM partition name.

  • slurm_time_limit (str) – SLURM time limit (e.g. “8:00:00”).

  • slurm_cpus (int) – Number of CPUs per task.

  • slurm_memory_gb (int) – Memory in GB.

  • username (str) – Username (for job name).

  • project_slug (str) – Project slug (for job name).

Returns:

Command list ready for subprocess.run().

Return type:

list[str]

scitex_container.apptainer.build_shell_in_allocation_command(job_id, instance_name, username='')[source]

Build srun --overlap command to attach a shell inside an existing allocation.

Parameters:
  • job_id (str) – SLURM job ID of the running allocation.

  • instance_name (str) – Name of the apptainer instance to exec into.

  • username (str) – Username for the shell session (used for user identity setup).

Returns:

Command list ready for os.execvpe or pty.fork.

Return type:

list[str]

scitex_container.apptainer.build_srun_command(container_path, username, host_user_dir, host_project_dir, project_slug, dev_repos=None, host_mounts=None, texlive_prefix='', slurm_partition='compute', slurm_time_limit='8:00:00', slurm_cpus=4, slurm_memory_gb=16, screen_session='scitex-0')[source]

Build the complete srun + apptainer command list.

Combines the SLURM resource flags with the apptainer exec arguments produced by build_exec_args(), launching a login bash shell directly (no screen).

Parameters:
  • container_path (str) – Path to the SIF file or sandbox directory.

  • username (str) – Username for the session.

  • host_user_dir (Path) – Host path to the user’s home directory.

  • host_project_dir (Path) – Host path to the project directory.

  • project_slug (str) – Project identifier.

  • dev_repos (list[dict], optional) – Dev repo dicts with name and host_path keys.

  • host_mounts (list[dict], optional) – Generic host mount dicts.

  • texlive_prefix (str) – Host prefix for TeX Live.

  • slurm_partition (str) – SLURM partition name.

  • slurm_time_limit (str) – SLURM time limit (e.g. “8:00:00”).

  • slurm_cpus (int) – Number of CPUs per task.

  • slurm_memory_gb (int) – Memory in GB.

  • screen_session (str) – Deprecated — ignored. Kept for backward compatibility.

Returns:

Flat list ready to be passed to os.execvpe or subprocess.Popen.

Return type:

list[str]

scitex_container.apptainer.cleanup(containers_dir, keep=3)[source]

Remove old scitex-v*.sif files, keeping the N most recent.

Never removes the active version (current.sif target) or any scitex-base-v*.sif base images.

Parameters:
  • containers_dir (Path) – Directory containing SIF files.

  • keep (int) – Number of most-recent versioned SIFs to keep (default: 3).

Returns:

Paths of removed SIF files.

Return type:

list[Path]

scitex_container.apptainer.cleanup_sandboxes(containers_dir, keep=5)[source]

Remove old sandbox directories, keeping the N most recent.

Never removes the active sandbox (current-sandbox symlink target).

Parameters:
  • containers_dir (Path) – Directory containing sandbox directories.

  • keep (int) – Number of most-recent sandboxes to keep (default: 5).

Returns:

Paths of removed sandbox directories.

Return type:

list[Path]

scitex_container.apptainer.cleanup_sifs(containers_dir, keep=0)[source]

Remove SIF files and related artifacts.

Removes *.sif, *.sif.old, *.sif.backup.* files and the current.sif symlink.

Parameters:
  • containers_dir (Path) – Directory containing SIF files.

  • keep (int) – Number of most-recent versioned SIFs to keep (default: 0).

Returns:

Paths of removed files.

Return type:

list[Path]

scitex_container.apptainer.deploy(source_dir, target_dir=PosixPath('/opt/scitex/singularity'))[source]

Copy active SIF and base SIF to target directory.

Copies the currently active scitex-v*.sif and the latest scitex-base-v*.sif to target_dir, then recreates the current.sif symlink there. Uses sudo for the copy.

Parameters:
  • source_dir (Path) – Directory containing the built SIF files.

  • target_dir (Path) – Deployment target directory (default: /opt/scitex/singularity).

Raises:
Return type:

None

scitex_container.apptainer.detect_container_cmd()[source]

Detect apptainer or singularity command.

Returns:

The container command name (‘apptainer’ or ‘singularity’).

Return type:

str

Raises:

FileNotFoundError – If neither command is found.

scitex_container.apptainer.find_containers_dir()[source]

Find the containers directory.

Search order: 1. ./containers/ (current working directory) 2. Package-relative containers/ (scitex-container source tree) 3. ~/.scitex/containers/ (user-managed)

Returns:

Path to the containers directory.

Return type:

Path

Raises:

FileNotFoundError – If no containers directory is found.

scitex_container.apptainer.freeze(sif_path, output_dir=None)[source]

Extract pinned versions from a built SIF.

Parameters:
  • sif_path (str or Path) – Path to the .sif file.

  • output_dir (str or Path, optional) – Directory for lock files. Defaults to same dir as .sif.

Returns:

Mapping of lock file type to path: {pip, dpkg, node}.

Return type:

dict[str, Path]

Raises:

FileNotFoundError – If SIF file or container command not found.

scitex_container.apptainer.get_active_sandbox(containers_dir)[source]

Read current-sandbox symlink to determine active sandbox version.

Parameters:

containers_dir (Path) – Directory containing the current-sandbox symlink.

Returns:

Timestamp string of the active sandbox, or None if no symlink.

Return type:

str or None

scitex_container.apptainer.get_active_version(containers_dir)[source]

Read current.sif symlink to determine active version.

Parameters:

containers_dir (Path) – Directory containing the current.sif symlink.

Returns:

Version string of the active SIF, or None if no symlink exists or it does not point to a valid versioned SIF.

Return type:

str or None

scitex_container.apptainer.is_sandbox(path)[source]

Check if path is a sandbox directory (not a SIF image).

A path ending in .sif is treated as a SIF image; anything else (including bare directory names or paths ending in -sandbox) is treated as a sandbox directory.

Parameters:

path (str or Path) – Path to check.

Returns:

True if path is a sandbox directory, False if it is a SIF image.

Return type:

bool

scitex_container.apptainer.list_sandboxes(containers_dir)[source]

List all versioned sandbox directories with metadata.

Parameters:

containers_dir (Path) – Directory containing sandbox directories.

Returns:

Each dict has keys: version, path, date, active. Sorted by modification time (newest first).

Return type:

list[dict]

scitex_container.apptainer.list_versions(containers_dir)[source]

List all versioned SIFs with metadata.

Parameters:

containers_dir (Path) – Directory containing SIF files.

Returns:

Each dict contains keys: version, path, size, date, active. Sorted by modification time (newest first).

Return type:

list[dict]

scitex_container.apptainer.rollback(containers_dir, use_sudo=False)[source]

Switch to the version before the current one (by modification time).

Parameters:
  • containers_dir (Path) – Directory containing SIF files.

  • use_sudo (bool) – If True, run symlink commands via sudo.

Returns:

Version string that is now active after rollback.

Return type:

str

Raises:

RuntimeError – If there is no current version or no previous version to roll back to.

scitex_container.apptainer.rollback_sandbox(containers_dir, use_sudo=False)[source]

Switch to the sandbox before the current one (by modification time).

Parameters:
  • containers_dir (Path) – Directory containing sandbox directories.

  • use_sudo (bool) – If True, run symlink commands via sudo.

Returns:

Timestamp string of the now-active sandbox.

Return type:

str

Raises:

RuntimeError – If there is no current sandbox or no previous one to roll back to.

scitex_container.apptainer.sandbox_configure_ps1(sandbox_dir, default_ps1='\\\\W $ ')

Set PS1 prompt in a sandbox’s environment script.

Writes a shell snippet that reads SCITEX_CLOUD_APPTAINER_PS1 at runtime, falling back to default_ps1. Users override by passing --env SCITEX_CLOUD_APPTAINER_PS1='(mylab) \\W $ ' to apptainer.

Apptainer’s 99-base.sh defaults to PS1="Apptainer> " only when PS1 is unset. Setting PS1 in 90-environment.sh (the %environment section) runs first and prevents that.

Parameters:
  • sandbox_dir (str or Path) – Path to the sandbox directory.

  • default_ps1 (str) – Default PS1 when SCITEX_CLOUD_APPTAINER_PS1 is not set.

Return type:

None

scitex_container.apptainer.sandbox_create(source, containers_dir=None, *, output_dir=None)

Build a sandbox directory from a SIF image or .def file.

Creates a timestamped sandbox (sandbox-YYYYMMDD_HHMMSS/) and updates the current-sandbox symlink to point to it.

Parameters:
  • source (str or Path) – Path to the source .sif file or .def file.

  • containers_dir (str or Path, optional) – Parent directory for sandbox output and symlink. Defaults to source file’s parent directory.

  • output_dir (str or Path, optional) – Explicit output path (overrides timestamped naming).

Returns:

Path to the created sandbox directory.

Return type:

Path

Raises:
scitex_container.apptainer.sandbox_maintain(sandbox_dir, command)

Run a command inside a sandbox with –writable –fakeroot flags.

Intended for admin maintenance tasks (installing packages, etc.). For user sessions, use –writable-tmpfs instead.

Parameters:
  • sandbox_dir (str or Path) – Path to the sandbox directory.

  • command (list[str]) – Command to execute inside the sandbox.

Returns:

Return code of the executed command.

Return type:

int

Raises:

FileNotFoundError – If the sandbox directory does not exist or apptainer is not found.

scitex_container.apptainer.sandbox_to_sif(sandbox_dir, output_sif)

Convert a sandbox directory back to a SIF image.

Parameters:
  • sandbox_dir (str or Path) – Path to the source sandbox directory.

  • output_sif (str or Path) – Path for the output .sif file.

Returns:

Path to the created .sif file.

Return type:

Path

Raises:
scitex_container.apptainer.sandbox_update(sandbox_dir, *, proj_root=None, packages=None, install_deps=False)

Incrementally update ecosystem packages inside an existing sandbox.

Runs pip install for each package from local repos, avoiding a full sandbox rebuild. Ideal for active development.

Parameters:
  • sandbox_dir (str or Path) – Path to the sandbox directory (or current-sandbox symlink).

  • proj_root (str or Path, optional) – Directory containing all ecosystem repos. Defaults to ~/proj.

  • packages (tuple[str, ...], optional) – Package names to install. Defaults to all ecosystem packages.

  • install_deps (bool) – If True, install dependencies too. If False (default), uses --no-deps for faster installs.

Returns:

Mapping of package name to result: “ok”, “failed”, or “skipped”.

Return type:

dict[str, str]

scitex_container.apptainer.status(containers_dir=None)[source]

List available containers and their status.

Parameters:

containers_dir (str or Path, optional) – Directory containing .def files. Auto-detected if not given.

Returns:

List of container info dicts with keys: name, def_path, sif_path, sif_size, sif_date, hash_current, hash_stored, needs_rebuild.

Return type:

list[dict]

scitex_container.apptainer.switch_sandbox(version, containers_dir, use_sudo=False)[source]

Atomically switch current-sandbox symlink to sandbox-{version}/.

Uses ln -sfn to create a temporary symlink, then mv -Tf for an atomic rename on the same filesystem.

Parameters:
  • version (str) – Target timestamp string (e.g. “20260225_173700”).

  • containers_dir (Path) – Directory containing sandbox directories.

  • use_sudo (bool) – If True, run ln/mv via sudo.

Raises:
Return type:

None

scitex_container.apptainer.switch_version(version, containers_dir, use_sudo=False)[source]

Atomically switch current.sif symlink to scitex-v{version}.sif.

Uses ln -sf to create a temporary symlink, then mv -Tf for an atomic rename on the same filesystem.

Parameters:
  • version (str) – Target version string (e.g. “2.19.5”).

  • containers_dir (Path) – Directory containing SIF files.

  • use_sudo (bool) – If True, run ln/mv via sudo (needed for /opt/scitex paths).

Raises:
Return type:

None

scitex_container.apptainer.verify(sif_path, def_path=None, lock_dir=None)[source]

Verify container integrity.

Checks: 1. SIF exists and computes its SHA256 2. If def_path given, compares .def hash against stored .def-hash 3. If lock files exist, runs pip freeze / dpkg-query inside the SIF

and compares against stored lock files

Parameters:
  • sif_path (str or Path) – Path to the .sif file to verify.

  • def_path (str or Path, optional) – Path to the .def file that should have produced this SIF.

  • lock_dir (str or Path, optional) – Directory containing lock files (requirements-lock.txt, dpkg-lock.txt). Defaults to same directory as the SIF.

Returns:

Verification results:

{
    "sif": {"path": "...", "sha256": "...", "exists": True},
    "def_origin": {"status": "pass|fail|skip", "detail": "..."},
    "pip_lock": {"status": "pass|fail|skip", "detail": "...", "diff_count": 0},
    "dpkg_lock": {"status": "pass|fail|skip", "detail": "...", "diff_count": 0},
    "overall": "pass|fail"
}

Return type:

dict

scitex_container.docker

Docker container management — rebuild, restart, status, and mount helpers.

scitex_container.docker.get_dev_mounts(repos)[source]

Generate Docker volume mount strings for development repositories.

Each entry in repos should have at minimum a "host" key with the host-side path, and a "container" key with the container-side path. An optional "mode" key ("ro" or "rw") defaults to "ro".

Parameters:

repos (list[dict]) –

Repository mount specifications:

[
    {"host": "../../scitex-python", "container": "/scitex-python"},
    {"host": "/abs/path/to/myrepo", "container": "/myrepo", "mode": "rw"},
]

"host" paths may be absolute or relative; relative paths are returned as-is so that Docker Compose can resolve them relative to the compose file location.

Returns:

Volume strings suitable for use in a Docker Compose volumes list or as -v arguments to docker run:

[
    "./../../scitex-python:/scitex-python:ro",
    "/abs/path/to/myrepo:/myrepo:rw",
]

Return type:

list[str]

scitex_container.docker.rebuild(env='dev', project_dir=None)[source]

Rebuild Docker containers without using the cache.

Runs: docker compose -f <compose_file> build --no-cache

Parameters:
  • env (str) – Environment name used to locate the compose file.

  • project_dir (str or Path or None) – Explicit directory containing the compose file. When None, the function walks upward from the current working directory.

Returns:

Exit code of the docker compose command (0 = success).

Return type:

int

scitex_container.docker.restart(env='dev', project_dir=None)[source]

Restart Docker containers (down then up).

Runs: docker compose -f <compose_file> down then: docker compose -f <compose_file> up -d

Parameters:
  • env (str) – Environment name used to locate the compose file.

  • project_dir (str or Path or None) – Explicit directory containing the compose file.

Returns:

Exit code of the final up -d command (0 = success). If down fails its exit code is returned instead.

Return type:

int

scitex_container.docker.status(env='dev', project_dir=None)[source]

Get Docker container status for the given compose environment.

Runs: docker compose -f <compose_file> ps --format json

Parameters:
  • env (str) – Environment name used to locate the compose file.

  • project_dir (str or Path or None) – Explicit directory containing the compose file.

Returns:

Status information:

{
    "compose_file": "/path/to/docker-compose.yml",
    "containers": [
        {
            "name": "myapp_web_1",
            "state": "running",
            "image": "myapp:latest",
            "raw": {...},   # original JSON from docker compose ps
        },
        ...
    ],
    "returncode": 0,
}

Return type:

dict

scitex_container.host

Host package management — install, verify, and mount host-level tools.

scitex_container.host.check_packages()[source]

Check which host packages are installed.

Returns:

Structured status per package group:

{
    "texlive": {
        "installed": True,
        "version": "pdfTeX 3.141592653...",
        "binaries": ["pdflatex", "bibtex", ...],
    },
    "imagemagick": {
        "installed": True,
        "version": "Version: ImageMagick 6.9...",
        "binaries": ["convert", "identify"],
    },
}

Return type:

dict

scitex_container.host.get_mount_config(texlive_prefix='', host_mounts_raw='')[source]

Parse mount configuration and return structured bind mount info.

Parameters:
  • texlive_prefix (str) – Installation prefix for TeXLive (e.g. /usr). When empty, defaults to /usr if TeXLive binaries are found there, otherwise skips TeXLive mounts.

  • host_mounts_raw (str) – Colon-separated raw bind specs in host:container or host:container:mode format, separated by commas or newlines. Example: "/data:/data:ro,/scratch:/scratch"

Returns:

Structured mount information:

{
    "bind_args": ["--bind", "/usr/share/texlive:/usr/share/texlive:ro", ...],
    "path_additions": ["/usr/bin"],
    "mounts": [{"host": "...", "container": "...", "mode": "ro"}, ...],
}

Return type:

dict

scitex_container.host.get_texlive_binds(prefix='/usr')[source]

Generate bind mount entries for TeXLive.

Parameters:

prefix (str) – Installation prefix (typically /usr for system-wide apt installs).

Returns:

Each entry has keys host, container, and mode:

[
    {"host": "/usr/share/texlive", "container": "/usr/share/texlive", "mode": "ro"},
    {"host": "/usr/bin/pdflatex",  "container": "/usr/bin/pdflatex",  "mode": "ro"},
    ...
]

Return type:

list[dict]

scitex_container.host.install_packages(texlive=False, imagemagick=False, all=False, check_only=False)[source]

Install host packages by calling the shell script.

Parameters:
  • texlive (bool) – Install TeXLive packages.

  • imagemagick (bool) – Install ImageMagick.

  • all (bool) – Install all packages (overrides texlive/imagemagick flags).

  • check_only (bool) – Run the script in –check mode without installing anything.

Returns:

Status per package group:

{
    "texlive": {"status": "installed", "returncode": 0},
    "imagemagick": {"status": "skipped", "returncode": None},
    "script": "/abs/path/to/install-host-packages.sh",
}

Return type:

dict

Raises:

FileNotFoundError – If the install script cannot be found.