Skip to main content

☢️ Nuclear

GitHub version (latest SemVer) PyPI Github Pages Documentation Status codecov GitHub Workflow Status

Nuclear is a binding glue for CLI applications. It consists of tools for building CLI applications in Python, including:

CLI Demo

from nuclear import CliBuilder

cli = CliBuilder()

@cli.add_command('hello')
def say_hello(name: str, decode: bool = False, repeat: int = 1):
    """
    Say hello
    :param decode: Decode name as base64
    """
    message = f"I'm a {b64decode(name).decode() if decode else name}!"
    print(' '.join([message] * repeat))

@cli.add_command('calculate', 'factorial')
def calculate_factorial(n: int):
    """Calculate factorial"""
    print(reduce(lambda x, y: x * y, range(1, n + 1)))

@cli.add_command('calculate', 'primes')
def calculate_primes(n: int):
    """List prime numbers using Sieve of Eratosthenes"""
    print(sorted(reduce((lambda r, x: r - set(range(x**2, n, x)) if (x in r) else r), range(2, n), set(range(2, n)))))

cli.run()

See demo.py for a complete example.

Installation

python3 -m pip install --upgrade nuclear

You need Python 3.10 or newer.

📜 Sublog

Sublog is a nuclear's contextual logging system that allows you to:

  • display variables besides log messages: logger.debug('message', airspeed=20),
  • wrap errors with context: with add_context('ignition'),
  • catch errors and show traceback in a concise, pretty format: with error_handler().
from nuclear.sublog import logger, error_handler, add_context

with error_handler():
    logger.debug('checking engine', temperature=85.0, pressure='12kPa')
    with add_context('ignition', request=42):
        logger.info('ignition ready', speed='zero')
        with add_context('liftoff'):
            raise RuntimeError('explosion')

sublog demo

Context logger

Use nuclear.sublog.logger to log message with a pretty format out of the box.

Pass additional context variables as keyword arguments to display them in the log message.

from nuclear.sublog import logger

logger.info('info log')
logger.debug('debug log', var1=1, var2='two')
logger.info('not great not terrible', radioactivity=3.6)
logger.error('this is bad')
logger.exception(RuntimeError('this is worse'))

Error handler

Use nuclear.sublog.error_handler to catch errors and show traceback in a concise, pretty format.

from nuclear.sublog import error_handler

with error_handler():
    raise RuntimeError('explosion')

Wrapping context

Use nuclear.sublog.add_context to wrap code with additional context information. This will be included in in the log message, if an error occurs.

from nuclear.sublog import add_context

with add_context('reloading plugins'):
    with add_context('loading config'):
        raise RuntimeError('file is missing')

This will produce an error with the following message:

reloading plugins: loading config: file is missing

Note that while each individual part of the message may not provide a comprehensive explanation of the error, when combined, the whole message becomes highly informative. This is the core principle behind enriching errors with context.

🚀 Nuke - Task Runner

Nuke is a lightweight task runner built into Nuclear for automating project tasks. It serves as a replacement for Makefile.

Define tasks as simple Python functions in a nukefile.py:

from nuclear import nuke, logger

class Config:
    src_path: str = '/opt/dump'
    dst_path: str = '/media/user/DRIVE/'
    dry: bool = False

config, sh = nuke.init(Config)

def push():
    sh(f"rsync -avh --delete --size-only --info=progress2 '{src_path}/' '{dst_path}'")

def convert():
    sh(f'ffmpeg -i "{src_path}/input.mp4" "{dst_path}/audio.mp3"')

if __name__ == '__main__':
    nuke.run()

Run tasks from command line:

nuke push
# or
./nukefile.py push

# see available tasks
nuke
./nukefile.py

# dry run mode
nuke push --dry

# override config parameters
nuke convert --src_path=/src/dump

See Nuke documentation for detailed guide.

🐌 Shell utilities

Nuclear provides utilities for running system shell commands.

Basic usage:

from nuclear import shell

window_id: str = shell('xdotool getactivewindow')

shell function captures the stdout & stderr output of the shell command and returns it as a string. It may also print live stdout in real time (line by line) and capture output in case of errors.

It has a lot of possibilities thanks to its parameters:

  • cmd: str - shell command to run
  • workdir: Optional[Path] = None - working directory for the command
  • print_stdout: bool = False - whether to print live stdout in real time (line by line) from a subprocess
  • print_log: bool = False - whether to print a log message about running the command
  • raw_output: bool = False - whether to let subprocess manage stdout/stderr on its own instead of capturing it
  • independent: bool = False - whether to start an independent process that can outlive the caller process
  • output_file: Optional[Path] = None - optional file to write the output in real time

It returns the stdout of the command combined with stderr. In case of non-zero command exit code, shell raises CommandError exception.

Metadata

Release files for nuclear 2.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nuclear 2.10.0
File Size Uploaded
nuclear-2.10.0.tar.gz 42.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nuclear 2.10.0
File Interpreter ABI Platform
nuclear-2.10.0-py3-none-any.whl Python 3 none any Details

Total release size: 109.0 kB

Release files / nuclear-2.10.0.tar.gz

Download URL nuclear-2.10.0.tar.gz
Size 42.7 kB
Tags Source
SHA-256 checksum
How to use checksums
7fcc5f2f756f139f554e98fabab65001273f25a28d84752b2a8d20162f93ee2f
BLAKE2b-256 checksum
How to use checksums
0865109073cd2dfb4865b19439afebb2e6e10ecd0cc6b8a593a130c3507e8487
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.12.10

Release files / nuclear-2.10.0-py3-none-any.whl

Download URL nuclear-2.10.0-py3-none-any.whl
Size 66.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4c1d0630bdcfc21ba0e51212f2fd57dbd41936665b491989fca4906c7320424e
BLAKE2b-256 checksum
How to use checksums
e58c197821668f75221a86ac688015569a06491ba0dc2eb62774328abca67639
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.12.10

Release history Release notifications | RSS feed

This release

2.10.0 This release

2 release files

2.9.0

2 release files

2.8.1

2 release files

2.7.1

2 release files

2.7.0

2 release files

2.6.1

2 release files

2.6.0

2 release files

2.5.0

2 release files

2.3.1

2 release files

2.2.5

2 release files

2.2.4

2 release files

2.2.3

2 release files

2.2.2

2 release files

2.2.0

2 release files

2.1.2

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.4.6

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.0

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.12

2 release files

1.1.11

2 release files

1.1.10

2 release files

1.1.9

2 release files

1.1.8

2 release files

1.1.7

2 release files

1.1.6

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page