Code lines codecov CodeFactor CodeQL conda-forge Version conda-forge Downloads Continuous Integration Contributor Covenant GitHub Contributors Documentation Status License Merged PRs OpenSSF Best Practices OpenSSF Scorecard Platforms pre-commit pre-commit.ci Status PyPI Version PyPI Downloads Python Version Ruff

staged-script

Python is an ideal language for certain types of infrastructure automation. Automating what a user does manually often involves walking through a series of stages. A user may wish to run all the stages in series, or perhaps only a subset, and depending on how things go, certain stages may need to be retried. Once the script finishes running, it’d be ideal if it could tell the user exactly what was run, for the sake of easing replicability. staged-script aims to ease the development such automation scripts. It’s easy to get started with, but also provides significant power-user functionality for those who need it.

Installation

To get up and running with staged-script, simply

python3 -m pip install staged-script

Usage

Once the package is installed, you can simply

example/ex_0_the_basics.py
 1import sys
 2
 3from staged_script import StagedScript
 4
 5
 6class MyScript(StagedScript):
 7    @StagedScript.stage("hello", "Greeting the user")
 8    def say_hello(self) -> None:
 9        self.run("echo 'Hello World'", shell=True)
10
11    @StagedScript.stage("goodbye", "Bidding farewell")
12    def say_goodbye(self) -> None:
13        self.run("echo 'Goodbye World'", shell=True)
14
15    def main(self, argv: list[str]) -> None:
16        self.parse_args(argv)
17        try:
18            self.say_hello()
19            self.say_goodbye()
20        finally:
21            self.print_script_execution_summary()
22
23
24if __name__ == "__main__":
25    my_script = MyScript({"hello", "goodbye"})
26    my_script.main(sys.argv[1:])

Executing the script then yields

>>> ./ex_0_the_basics.py --stage hello goodbye
[07:34:19] ╭─────────────────────────────────────────────╮ staged_script.py:937
           │ Greeting the user                           │
           ╰─────────────────────────────────────────────╯
           Executing:  echo 'Hello World'                  staged_script.py:827
Hello World
           `hello` stage duration:  0:00:00.020772         staged_script.py:476
           ╭─────────────────────────────────────────────╮ staged_script.py:937
           │ Bidding farewell                            │
           ╰─────────────────────────────────────────────╯
           Executing:  echo 'Goodbye World'                staged_script.py:827
Goodbye World
           `goodbye` stage duration:  0:00:00.012504       staged_script.py:476
───────────────── ex_0_the_basics.py Script Execution Summary ─────────────────
                                                           staged_script.py:920
           ➤ Ran the following:

               ex_0_the_basics.py \
                   --stage hello goodbye \
                   --hello-retry-attempts 0 \
                   --hello-retry-delay 0 \
                   --hello-retry-timeout 60 \
                   --goodbye-retry-attempts 0 \
                   --goodbye-retry-delay 0 \
                   --goodbye-retry-timeout 60

           ➤ Commands executed:

               echo 'Hello World'
               echo 'Goodbye World'

           ➤ Timing results:

               ┏━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
               ┃ Stage   ┃ Duration       ┃
               ┡━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
               │ hello   │ 0:00:00.020772 │
               │ goodbye │ 0:00:00.012504 │
               ├─────────┼────────────────┤
               │ Total   │ 0:00:00.035295 │
               └─────────┴────────────────┘

           ➤ Script result:

               Success

─────────────── End ex_0_the_basics.py Script Execution Summary ───────────────

For more detailed usage information, see the Examples page. For implementation details, see the Reference documentation.

Contributing

The source repository for this module is on GitHub. See the project’s README and contributing guidelines for details on how to interact with the project.

Inspiration

Aspects of this functionality were inspired by the SPiFI Jenkins Pipeline plugin and the shell-logger Python package.