Skip to main content

Concise layer on top of subprocess, similar to sh project

Project description

lagoon

Concise layer on top of subprocess, similar to sh project

Support

If you see an error along the lines of:

ImportError: cannot import name 'zyx' from 'lagoon.text'

This means the app requires command zyx to be available, and you don't have it on your system. The solution is to install zyx in the usual way, e.g. via your package manager.

Usage examples

Unlike with plain old subprocess, stdout is returned by default. Use the print token to send it to console:

from lagoon.text import docker

docker.run.__rm[print]('hello-world')

Attributes are treated as arguments, and their underscores are converted to dashes. Arguments in brackets are not transformed except for conversion to string. Use the partial token to suppress launch via brackets, and use with to run a command in the background:

from lagoon.text import zcat
from lagoon.program import partial # Also works when imported from functools.
import sys

with zcat[partial]('/var/log/dmesg.1.gz') as f:
    for line in f:
        sys.stdout.write(line)

When there is just one value to return it is returned directly, otherwise CompletedProcess (or Popen in background case) is returned:

from lagoon.text import echo

assert 'word\n' == echo('word')
assert 'word\n' == echo('word', check = False).stdout
assert 0 == echo('word', check = False).returncode
assert 0 == echo[print]('word', check = False)

Defaults different to subprocess

  • The stdout is returned instead of being sent to console
  • CalledProcessError is raised if the exit status is not zero i.e. check is True
  • Environment variables are merged into the existing environment instead of replacing it
    • Set a variable to None to remove it from the environment
  • When importing from lagoon.text all 3 streams are in text mode, use lagoon.binary for binary mode

Irregular commands

You can use getattr if the command can't be imported in the usual way:

import lagoon.text

gplusplus = getattr(lagoon.text, 'g++')

Alternatively create a ProgramHandle manually:

from lagoon.program import Program
from shutil import which

gplusplus = Program.text(which('g++'))

Most commands are dash-separated so lagoon.text/lagoon.binary translate that to underscore for convenience. If your command already has an underscore in its name, it will be in lagoon.sic.text/lagoon.sic.binary instead:

from lagoon.text import debian_distro_info
from lagoon.sic.text import lsb_release

In the rare case a command has at least one dash, but translating its dashes to underscores would result in an unimportable name, it too will be in the sic modules:

import lagoon.sic.text

gplusplus_11 = getattr(lagoon.sic.text, 'g++-11')

Commands

dirpile

Using OverlayFS create a merged view of the given (read only) dirs plus a (writable) temporary dir, print its path, and stay running until stdin is closed. The first given directory is the lowest in the pile (this is unlike the lowerdir mount option). This program requires root and is designed to be invoked via sudo.

API

dkrcache

NORMAL

Accept normal outcomes.

ABRUPT

Accept abrupt outcomes.

ALWAYS

Accept all outcomes.

NEVER

Do not accept any outcome.

ExpensiveTask Objects

class ExpensiveTask()

Arbitrary task accelerated by Docker cache.

__init__
def __init__(context, discriminator, task)

Create a task keyed by context directory and discriminator string.

run
def run(force=NEVER, cache=NORMAL)

Run the task, where force can be used to ignore a cached outcome, and cache can be used to deny caching an outcome.

dkrcache.util

ContextStream Objects

class ContextStream()

Fully customisable docker build context.

open
@classmethod
@contextmanager
def open(cls, dockerstdin)

Attach to the given stdin of docker build, which should have been given - as context.

put
def put(name, path)

Add the given path as the given archive name.

putstream
def putstream(name, stream)

Add the given stream as the given archive name.

mkdir
def mkdir(name)

Create a directory in the context.

iidfile
@contextmanager
def iidfile()

Context manager yielding an object with args to pass to docker build, and a read function to get the image ID.

lagoon.binary

Like lagoon.text module but ProgramHandle objects are in binary mode.

lagoon.program

Program Objects

class Program()

Normally import an instance from lagoon.text or lagoon.binary module instead of instantiating manually.

text
@classmethod
def text(cls, path)

Return text mode ProgramHandle for the executable at the given path.

binary
@classmethod
def binary(cls, path)

Return binary mode ProgramHandle for executable at given path.

ProgramHandle Objects

class ProgramHandle(Parabject)

__getattr__
def __getattr__(name)

Add argument, where underscore means dash.

__getitem__
def __getitem__(key)

Apply a style, e.g. partial to suppress execution or print to send stdout to console.

__call__
def __call__(*args, **kwargs)

Run program in foreground with additional args. Accepts many subprocess kwargs. Use partial style to suppress execution, e.g. before running in background. Otherwise return CompletedProcess, or one of its fields if the rest are redirected, or None if all fields redirected.

__enter__
def __enter__()

Start program in background yielding the Popen object, or one of its fields if the rest are redirected.

NOEOL Objects

@singleton
class NOEOL()

Style to strip trailing newlines from stdout, in the same way as shell does.

ONELINE
def ONELINE(text)

Style to assert exactly one line of output, using splitlines.

lagoon.sic.binary

Commands with an underscore already in their name, binary mode.

lagoon.sic.text

Commands with an underscore already in their name, text mode.

lagoon.text

Text mode instances of ProgramHandle for every executable, with dash translated to underscore e.g. from lagoon.text import pkg_config for pkg-config.

lagoon.url

lagoon.util

unmangle
def unmangle(name)

Undo name mangling.

atomic
@contextmanager
def atomic(path)

Context manager yielding a temporary Path for atomic write to the given path. Parent directories are created automatically. Also suitable for making a symlink atomically. Leaves the given path unchanged if an exception happens.

threadlocalproperty Objects

class threadlocalproperty()

Like property but each thread has its own per-object values.

__init__
def __init__(defaultfactory)

The defaultfactory should return the initial value per object (per thread).

onerror
@contextmanager
def onerror(f)

Context manager that runs the given function if an exception happens, like finally excluding the happy path.

mapcm
@contextmanager
def mapcm(f, obj)

Invoke obj as a context manager, apply f to its yielded value, and yield that. For example apply Path to the string yielded by TemporaryDirectory().

stripansi
def stripansi(text)

Remove ANSI control sequences from the given text, to make it black and white.

HarnessCase Objects

class HarnessCase(TestCase)

Enter context managers in setUp and exit them in tearDown.

harness
def harness()

Must yield exactly once.

wrappercli
def wrappercli()

Same as sys.argv[1:] if -- is present there, otherwise -- is prepended. This is for sending all options to a wrapped command by default.

multifork

screen

GNU Screen interface, smoothing over its many gotchas.

stuffablescreen
def stuffablescreen(doublequotekey)

Return text mode ProgramHandle for screen, with the given environment variable set to double quote.

Stuff Objects

class Stuff()

__init__
def __init__(session, window, doublequotekey)

Target the given screen session and window, using the given environment variable for double quote.

__call__
def __call__(text)

Send the given text so that it is received literally.

eof
def eof()

Send EOF, may have no effect if not at the start of a line.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lagoon-56.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lagoon-56-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file lagoon-56.tar.gz.

File metadata

  • Download URL: lagoon-56.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for lagoon-56.tar.gz
Algorithm Hash digest
SHA256 3989490c7dfb310d8dad82e86616775d49b152c7d895fd8cfd81c04a8c7f0c87
MD5 9ee88028f365e47f018f6b4d23e297c1
BLAKE2b-256 ff6dcb5672326319b101ba63929f4ba5a7a7ef5b95fad0b3ae9782564ece464b

See more details on using hashes here.

File details

Details for the file lagoon-56-py3-none-any.whl.

File metadata

  • Download URL: lagoon-56-py3-none-any.whl
  • Upload date:
  • Size: 19.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for lagoon-56-py3-none-any.whl
Algorithm Hash digest
SHA256 afd8a01a17038f129be092862098b5aa5c5b57d83a97b0ed3d91e05528c5f7fd
MD5 ca5d47f8e4d35d92029feac9fa13fd1f
BLAKE2b-256 09b82e9aa7a5df43745e2e7bf1f2eae852d64ec0e7f69f3783e74328c5c3150c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page