Python API

The scrippy_core package provides the following objects to your scripts:

Object Purpose
scrippy_core.ScriptContext The execution context
scrippy_core.logger The Scrippy logger
scrippy_core.ScrippyCoreError The Scrippy exception
scrippy_core.env The Scrippy directories

The configuration object, available through _context.config, is described below.

Importing scrippy_core

import scrippy_core
from scrippy_core import logger, ScrippyCoreError

Importing scrippy_core initializes Scrippy:

  1. The main configuration files are read and merged.
  2. The logger is set up, with its terminal output.
  3. The header of the running script (the Python __main__ module) is parsed, the command line options are parsed and checked. The informational options (--help, --hist...) are handled and exit.
  4. --no-stdout and --debug are applied, and the secret options are registered.

As a consequence:

  • scrippy_core must be imported by the script being executed, which must have a declarative header. It can not be imported from an interactive Python interpreter.
  • scrippy_core must be imported before any other Scrippy module (scrippy_template, scrippy_remote...).

Warning: Importing another Scrippy module before scrippy_core creates the shared logger without its Scrippy features: Secrets are not redacted, logger.log_section() is not available, and a script declaring a secret fails with AttributeError: 'Logger' object has no attribute 'add_secret'.

ScriptContext

scrippy_core.ScriptContext(retention=50, workspace=True)

The execution context, to be used as a context manager enclosing the whole content of the main() function:

def main():
  with scrippy_core.ScriptContext() as _context:
    ...

Parameters

Parameter Type Description Default
retention Integer The number of executions kept in the history 50
workspace Boolean Create a temporary workspace True

Attributes

Attribute Type Content
args argparse.Namespace The options and arguments
config Config The configuration of the script (available once entered)
env Dictionary The Scrippy directories
workspace_path String The path of the temporary workspace, None if disabled (available once entered)
name String The script name, without extension (i.e: disk_watch)
filename String The script file name (i.e: disk_watch.py)
logger ScrippyLogger The Scrippy logger

Entering the context

When entering the context, Scrippy:

  1. Loads and checks the configuration file, then applies the [log] level
  2. Registers the secret configuration values
  3. Checks the authorized users, then the authorized groups
  4. Registers the execution and waits for an execution slot if needed
  5. Opens the log file and records the execution in the history, unless --no-log-file is used
  6. Creates the workspace, unless disabled

If any step fails, the steps already done are undone and the error is handled as described below.

Leaving the context

When leaving the context, whatever happened inside, Scrippy:

  1. Deletes the workspace
  2. Records the end of the execution in the history: End date, duration, exit status and error name
  3. Unregisters the execution
  4. Handles the error, if any:
    • No error, sys.exit() or sys.exit(0): Nothing is done.
    • sys.exit(n): A CRITICAL message [SystemExit]: n is logged and the script exits with the status n.
    • Any other exception: A CRITICAL message [<exception name>]: <message> is logged, followed by the stack trace in DEBUG level, and the script exits with the status 1.

Every cleanup step is always executed, even if a previous one failed.

logger

from scrippy_core import logger

The Scrippy logger is a ScrippyLogger, a subclass of the standard logging.Logger named scrippy.main. All Scrippy modules log through it.

It provides the standard methods: debug(), info(), warning(), error(), critical(), exception(), log()... and the following ones:

Method Description
add_secret(secret) Adds a value to the vault: Every occurrence of str(secret) is replaced by ******* in all further messages. Empty values are ignored
log_line(level=logging.INFO) Logs a line of 80 dashes
log_section(prefix, message, level=logging.INFO) Logs [<prefix>] <message> between two lines of dashes
import logging
from scrippy_core import logger

logger.log_section("disk_watch", "Checking mount points", level=logging.DEBUG)
logger.add_secret(session_token)

Secrets are redacted from the formatted message, including the arguments of a % style call such as logger.info("%s", secret).

Output format

[20261008 19:05:05] [INFO    ] [+] /: 34.9% used

The terminal output is colored when the standard output is a terminal whose TERM environment variable is linux, xterm, xterm-256color, screen, screen-256color, tmux or tmux-256color. Log files always contain color codes.

ScrippyCoreError

from scrippy_core import ScrippyCoreError

raise ScrippyCoreError("Invalid thresholds")

The exception raised by scrippy_core for all its errors. Raise it to stop the script with a clear message. The message is available through the message attribute.

env

scrippy_core.env

The dictionary of the Scrippy directories, resulting from the merge of the main configuration files: confdir, datadir, histdir, logdir, reportdir, templatedir, tmpdir. Also available as _context.env.

Config

The configuration of the script, available as _context.config once the context is entered. See the Configuration file step of the tutorial.

get()

config.get(section, key, param_type="str")

Returns the value of key in section, converted to param_type.

param_type Returned type Conversion
str str None
int int int()
float float float()
bool bool 1, yes, true, on / 0, no, false, off (case insensitive)

Raises a ScrippyCoreError:

Message Cause
Missing or unknown configuration section: [<section>] The section does not exist
Missing or unknown configuration parameter: [<section>][<key>] The key does not exist
Type error: [<section>][<key>] is not of type '<type>' The value can not be converted
Usage error: Unknown parameter type: '<type>' param_type is not one of the above

has()

config.has(section, key)

Returns True if key exists in section, False otherwise (including when the section does not exist).

get_section()

config.get_section(section)

Returns the keys of section as a dictionary of strings. Raises a ScrippyCoreError if the section does not exist.

config_filename

The path of the configuration file of the script, whether it exists or not.

File format

The configuration file is read with the Python configparser module, with its default settings:

  • Section names are case sensitive. Key names are not: They are converted to lower case.
  • Values can span several lines, the continuation lines being indented.
  • %(key)s is replaced by the value of key from the same section or from the [DEFAULT] section. A literal % must be written %%.
  • The keys of the [DEFAULT] section are available in every section.
  • Comments must be on their own line, starting with # or ;.