Session Decorator (@stx.session)

The @stx.session decorator is the primary entry point for SciTeX scripts. It wraps a function to provide automatic CLI generation, output directory management, configuration injection, and provenance tracking.

Basic Usage

import scitex as stx

@stx.session
def main(
    data_path="data.csv",       # CLI: --data-path data.csv
    threshold=0.5,              # CLI: --threshold 0.7
    CONFIG=stx.INJECTED,        # Auto-injected session config
    plt=stx.INJECTED,           # Pre-configured matplotlib
    logger=stx.INJECTED,        # Session logger
):
    """Analyze experimental data."""
    data = stx.io.load(data_path)
    result = process(data, threshold)
    stx.io.save(result, "output.csv")
    return 0  # exit code (0 = success)

if __name__ == "__main__":
    main()  # No arguments triggers CLI mode

Run from the command line:

python my_script.py --data-path experiment.csv --threshold 0.3
python my_script.py --help  # Shows all parameters with defaults

How It Works

Session lifecycle: main() → Parse CLI → Create dir → Load config → Execute → SUCCESS or ERROR

When main() is called without arguments, the decorator:

  1. Parses CLI arguments from the function signature (type hints and defaults become argparse options)

  2. Creates a session directory under script_out/RUNNING/{session_id}/

  3. Loads configuration from ./config/*.yaml files into CONFIG

  4. Injects globals (CONFIG, plt, COLORS, logger, rngg) into the function

  5. Redirects stdout/stderr to log files

  6. Executes the function with parsed arguments

  7. Moves output from RUNNING/ to FINISHED_SUCCESS/ (or FINISHED_ERROR/)

When called with arguments (e.g., main(data_path="x.csv")), the decorator is bypassed and the function runs directly – useful for testing and notebooks.

Output Directory Structure

Each run produces a self-contained output directory:

my_script_out/
+-- FINISHED_SUCCESS/
|   +-- 2026Y-02M-13D-14h30m15s_Z5MR/
|       +-- CONFIGS/
|       |   +-- CONFIG.yaml     # Frozen configuration
|       |   +-- CONFIG.pkl      # Pickled config
|       +-- logs/
|       |   +-- stdout.log      # Captured stdout
|       |   +-- stderr.log      # Captured stderr
|       +-- output.csv          # Your saved files
|       +-- sine.png            # Your saved figures
|       +-- sine.csv            # Auto-exported figure data
+-- FINISHED_ERROR/
|   +-- ...                     # Runs that returned non-zero
+-- RUNNING/
    +-- ...                     # Currently active sessions

The session ID format is YYYY-MM-DD-HH:MM:SS_XXXX where XXXX is a random 4-character suffix for uniqueness.

Injected Parameters

Use stx.INJECTED as the default value to receive auto-injected objects:

Parameter Name

Type

Description

CONFIG

DotDict

Session config with ID, SDIR_RUN, FILE, ARGS, plus all ./config/*.yaml values

plt

module

matplotlib.pyplot configured for the session (Agg backend, style settings)

COLORS

DotDict

Color palette for consistent plotting

logger

Logger

SciTeX logger writing to session log files

rngg

RandomStateManager

Reproducibility manager (seeds fixed by default)

Only request the parameters you need:

@stx.session
def main(n=100, CONFIG=stx.INJECTED):
    """Minimal example -- only CONFIG injected."""
    print(f"Session ID: {CONFIG.ID}")
    print(f"Output dir: {CONFIG.SDIR_RUN}")
    return 0

CONFIG Object

The injected CONFIG is a DotDict supporting both dictionary and dot-notation access:

CONFIG["MODEL"]["hidden_size"]   # dict-style
CONFIG.MODEL.hidden_size         # dot-style (equivalent)

It contains:

CONFIG.ID             # "2026Y-02M-13D-14h30m15s_Z5MR"
CONFIG.PID            # Process ID
CONFIG.FILE           # Path to the script
CONFIG.SDIR_OUT       # Base output directory
CONFIG.SDIR_RUN       # Current session's output directory
CONFIG.START_DATETIME # When the session started
CONFIG.ARGS           # Parsed CLI arguments as dict
CONFIG.EXIT_STATUS    # 0 (success), 1 (error), or None

Any YAML files in ./config/ are merged into CONFIG:

# ./config/EXPERIMENT.yaml
learning_rate: 0.001
batch_size: 32
# Accessible as:
CONFIG.EXPERIMENT.learning_rate  # 0.001
CONFIG.EXPERIMENT.batch_size     # 32

Decorator Options

@stx.session(verbose=True, agg=False, notify=True, sdir_suffix="v2")
def main(...):
    ...

Option

Type

Default

Description

verbose

bool

False

Enable verbose logging

agg

bool

True

Use matplotlib Agg backend (set False for interactive plots)

notify

bool

False

Send notification when session completes

sdir_suffix

str

None

Append suffix to output directory name

Best Practices

  1. One session per script – each .py file should have one @stx.session function

  2. Return 0 for success – the return value becomes the exit status

  3. Save outputs with stx.io.save – files go into the session directory and are provenance-tracked

  4. Put config in YAML – use ./config/*.yaml instead of hardcoding parameters

  5. Use stx.repro.fix_seeds() – already called by default via rngg

API Reference

scitex-session — @session decorator + lifecycle management (standalone).

scitex.session.start(sys=None, plt=None, file=None, sdir=None, sdir_suffix=None, args=None, os=None, random=None, np=None, torch=None, seed=42, agg=False, fig_size_mm=(160, 100), fig_scale=1.0, dpi_display=100, dpi_save=300, fontsize='small', autolayout=False, show_execution_flow=False, hide_top_right_spines=True, alpha=0.9, line_width=1.0, clear_logs=False, verbose=True)[source]

Initialize experiment session with reproducibility settings.

Parameters:
  • sys (module, optional) – Python sys module for I/O redirection

  • plt (module, optional) – Matplotlib pyplot module for plotting configuration

  • file (str, optional) – Script file path. If None, automatically detected

  • sdir (Union[str, Path], optional) – Save directory path

  • sdir_suffix (str, optional) – Suffix to append to save directory

  • args (object, optional) – Command line arguments or configuration object

  • seed (int, default=42) – Random seed for reproducibility

  • agg (bool, default=False) – Whether to use matplotlib Agg backend

  • verbose (bool, default=True) – Whether to print detailed information

Returns:

(CONFIGS, stdout, stderr, plt, COLORS, rng)

Return type:

tuple

scitex.session.close(CONFIG, message=':)', notify=False, verbose=True, exit_status=None, archive_format=None)[source]

Close experiment session and finalize logging.

Parameters:
  • CONFIG (DotDict) – Configuration dictionary from start()

  • message (str, default=':)') – Completion message

  • notify (bool, default=False) – Whether to send notification

  • verbose (bool, default=True) – Whether to print verbose output

  • exit_status (int, optional) – Exit status code (0=success, 1=error, None=finished)

  • archive_format (str, optional) – If set (e.g. “tar.gz”), replace the FINISHED dest dir with a single archive file. None (default) preserves the original copytree-only behavior bit-for-bit.

scitex.session.running2finished(CONFIG, exit_status=None, remove_src_dir=True, max_wait=60, archive_format=None)[source]

Move session from RUNNING to FINISHED directory.

Parameters:
  • CONFIG (dict) – Session configuration dictionary

  • exit_status (int, optional) – Exit status code (0=success, 1=error, None=finished)

  • remove_src_dir (bool, default=True) – Whether to remove source directory after copy

  • max_wait (int, default=60) – Maximum seconds to wait for copy operation

  • archive_format (str, optional) – If set (e.g. “tar.gz”), replace the FINISHED dest dir with a single archive file (1 inode instead of N). None (default) preserves the original copytree-only behavior bit-for-bit.

Returns:

Updated configuration with new SDIR

Return type:

dict

scitex.session.session(func=None, *, verbose=False, agg=True, notify=False, sdir_suffix=None, archive_format=None, **session_kwargs)[source]

Decorator to wrap a function in a scitex session.

Automatically handles:

  • CLI argument parsing from the function signature

  • Session initialization (logging, output directories)

  • Execution

  • Cleanup

  • Error handling

This decorator is designed for script entry points. The decorated function should be called without arguments from if __name__ == '__main__': to trigger CLI parsing and session management.

Parameters:
  • func (callable, optional) – Function to wrap (set automatically by the decorator).

  • verbose (bool, default False) – Enable verbose logging.

  • agg (bool, default True) – Use matplotlib’s Agg backend (non-interactive).

  • notify (bool, default False) – Send notification on completion.

  • sdir_suffix (str, optional) – Suffix for the output directory name (defaults to function name).

  • archive_format (str, optional) – If set (e.g. "tar.gz"), replace FINISHED_SUCCESS/<session>/ with a single archive file (1 inode vs 7).

  • **session_kwargs – Additional session configuration parameters forwarded to scitex_session.start / scitex_session.close.

Returns:

The wrapped function; calling it with no arguments triggers CLI parsing + session management. Calling it with arguments bypasses session management entirely and invokes the function directly (useful for in-process tests).

Return type:

callable

Examples

Bare decorator (auto CLI from signature):

@stx.session
def analyze(data_path: str, threshold: float = 0.5):
    '''Analyze data file.'''
    data = stx.io.load(data_path)
    result = process(data, threshold)
    stx.io.save(result, "output.csv")
    return 0

if __name__ == '__main__':
    analyze()  # CLI mode with session management

# CLI: python script.py --data-path data.csv --threshold 0.7

Decorator with options:

@stx.session(verbose=True, notify=True)
def train_model(model_name: str, epochs: int = 10):
    '''Train ML model.'''
    # Available as globals: CONFIG, plt, COLORS, rngg, logger.
    logger.info(f"Session ID: {CONFIG['ID']}")
    logger.info(f"Output directory: {CONFIG['SDIR_RUN']}")
    # ... training code ...
    return 0

if __name__ == '__main__':
    train_model()

Notes

  • Function name can be anything (not just main).

  • Calling with arguments bypasses session management: analyze('/path', 0.5).

  • Only one session-managed function per script.

  • Do NOT call multiple @session decorated functions from one script.

  • Do NOT nest session-decorated function calls without arguments.

When called without arguments (CLI mode), the decorator injects these into the wrapped function’s module globals:

  • CONFIG (dict): Session configuration with ID, SDIR, paths, etc.

  • plt (module): matplotlib.pyplot configured for the session.

  • COLORS (CustomColors): Color palette for consistent plotting.

  • rngg (RandomStateManager): Reproducibility manager; creates named generators via rngg("name").

scitex.session.run(func, parse_args=None, **session_kwargs)[source]

Run a function with session management — explicit alternative to @session.

Parameters:
  • func (callable) – Function to run.

  • parse_args (callable, optional) – Custom argument parser. If None, an argparse parser is auto-generated from func’s signature via _create_parser().

  • **session_kwargs – Forwarded to scitex_session.start / close.

Return type:

Any

Returns:

  • int – Exit status. 0 on success; non-zero on failure (also re-raised).

  • Example::

    def main(args):

    # … your code … return 0

    if __name__ == ‘__main__’:

    stx.session.run(main)

class scitex.session.SessionManager[source]

Manages experiment sessions with tracking and lifecycle management.

create_session(session_id, config, script_path=None)[source]

Register a new session.

Parameters:
  • session_id (str) – Unique identifier for the session

  • config (Dict[str, Any]) – Session configuration dictionary

  • script_path (str, optional) – Path to the script being run

Return type:

None

close_session(session_id, status='success', exit_code=0)[source]

Mark a session as closed.

Parameters:
  • session_id (str) – Unique identifier for the session to close

  • status (str, optional) – Final status (success, failed, error)

  • exit_code (int, optional) – Exit code of the session

Return type:

None

get_active_sessions()[source]

Get all active sessions.

Returns:

Dictionary of active session information

Return type:

Dict[str, Any]

get_session(session_id)[source]

Get specific session information.

Parameters:

session_id (str) – Session ID to retrieve

Returns:

Session information dictionary

Return type:

Dict[str, Any]

list_sessions()[source]

Get all sessions (active and closed).

Returns:

Dictionary of all session information

Return type:

Dict[str, Any]

scitex.session.archive_session_dir(src_dir, format='tar.gz', remove_src=True, compresslevel=1)[source]

Compress a single session dir into a single archive file.

Writes to a temp path adjacent to the destination, then atomically renames into place. Only after the archive exists and passes a size sanity check do we delete the source (when remove_src=True). On any error the source is left untouched.

Returns:

Absolute path to the final archive file.

Return type:

Path

scitex.session.restore_session_archive(archive_path, dest_dir=None, remove_archive=False)[source]

Extract a session archive back into a session directory.

Extraction is done into a temp dir adjacent to the final destination and atomically renamed into place. If remove_archive=True the archive file is deleted only after a successful rename.

Returns:

Absolute path to the restored directory.

Return type:

Path

scitex.session.archive_existing(root, older_than_days=None, format='tar.gz', pattern=None, dry_run=True, max_dirs=None, track_bytes=False, use_fd=True)[source]

Bulk compress every session-shaped child of root.

Parameters:
  • track_bytes (bool, default False) – When True, run a per-candidate dir_size() (os.walk + getsize per file) so that bytes_in / bytes_out in the returned summary are populated. Off by default because the size accounting adds a measurable per-session overhead on top of the mandatory tar IO (observed on neurovista 2026-05-25: 80,408 sessions / 47 min wall-clock — the byte stats are a meaningful contributor).

  • use_fd (bool, default True) – Forwarded to iter_session_candidates. When True and fd is installed, candidate enumeration uses the parallel subprocess path; otherwise the Python iterdir+stat path.

Returns:

Summary {scanned, candidates, archived, skipped, failed, bytes_in, bytes_out}. bytes_in and bytes_out stay at 0 when track_bytes is False.

Return type:

dict

scitex.session.restore_existing(root, pattern='*.tar.gz', dest_root=None, remove_archive=False, dry_run=True, max_files=None, track_bytes=False)[source]

Bulk restore every archive matching pattern directly under root.

Returns:

Summary {scanned, candidates, restored, skipped, failed}.

Return type:

dict