Skip to main content

Shhell

Subprocess replacement done right with fancy API to build commands, autocompletion and typing support ✨

I was not satisfied with API of subprocess/sh/plumbum, so I decided to at least define how the perfect API should look like for me.

Coming soon, sometime or just never.

How I want API to look like:

import shhell

shhell.sh(c=shhell.curl(*'fsSL', 'https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh')).run()

which will be translated to:

sh -c "$(curl -fsSL 'https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh')"

shhell.<cmd>(...) will produce an instance of special class, which can invoke and get result from command both synchronously and asynchronously, allowing flexibility:

import asyncio
import shhell

OUTPUT_FILE = "example.mp4"

async def download():
    await shhell.curl(
        *'fsSL',
        "https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_1920_18MG.mp4",
        output=OUTPUT_FILE
    )

async def print_file_size():
    while True:
        await shhell.echo(f'\t{await shhell.stat(OUTPUT_FILE, printf="%s")}')
        await asyncio.sleep(0.1)

asyncio.run(
    asyncio.wait(
        [
            asyncio.create_task(download()), 
            asyncio.create_task(print_file_size())
        ],
        return_when=asyncio.FIRST_COMPLETED
    )
)

Pipes, redirects, subshells?

I like how plumbum deos this, i.e. using python magic methods allowing |, > support. In fact, if I'm going to write this library, I'm going to steal a lot of ideas from plumbum, changing little things that I don't like.

How autocompletion would even work?

Code generation, of course! However, it's not going to be easy, if achievable at all...

One of the options is generating signatures upon package build for executables available in PATH (expected args, types, docs) from -h/--help/man output for the command for linux/macOS. This option is only viable on CI/CD stages, however.

There should be api available for users to generate code structures for their own non-standard executables.

Note: all the generated code will serve only cosmetic purpose, whether a signature was generated for a specific executable or not, the runtime result should always remain the same.

So shhell/executables/cowsay.py would look like this:

from typing import Any, Literal
from shhell.command import Command
from shhell.executable import Executable

@Executable.from_dummy
def cowsay(
    *args: Literal["b", "d", "g", "p", "s", "t", "w", "y", "l", "n"],
    # __message this is positional only optional argument
    __message: str = ...,
    # these arguments are keyword only (e='??' will be converted to -e '??')
    e: Any = "eyes",
    f: Any = "cowfile",
    T: Any = "tongue",
    W: Any = "wrapcolumn",
) -> Command:
    """
    cow{say,think} version 3.03, (c) 1999 Tony Monroe
    Usage: cowsay [-bdgpstwy] [-h] [-e eyes] [-f cowfile]
          [-l] [-n] [-T tongue] [-W wrapcolumn] [message]
    """
...

However, I think it's better to have a separate file for each executable, and just add imports for them

Metadata

Release files for shhell 0.0.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 shhell 0.0.0
File Size Uploaded Provenance
shhell-0.0.0.tar.gz 3.7 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 7.9 kB

Release files / shhell-0.0.0.tar.gz

Download URL shhell-0.0.0.tar.gz
Size 3.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4d932cd59a2f10ca17828909177b47532340aa58e9b484ee442ea97533b582ba
BLAKE2b-256 checksum
How to use checksums
165c4f99e98163d0649c43b640563fc5a6dbdeffb9eb85b3143289ec0181c918
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.11 CPython/3.9.5 Darwin/20.5.0

Release files / shhell-0.0.0-py3-none-any.whl

Download URL shhell-0.0.0-py3-none-any.whl
Size 4.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e98bfac178ce43d46af7951a24cf712bac5b7ae3fb9cfe3c8772dc22dfc4787c
BLAKE2b-256 checksum
How to use checksums
7e693d609a1464281f4b467f3b852ee3b2304018067f1fc8d7d7d1841162ac8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.11 CPython/3.9.5 Darwin/20.5.0

Security for shhell 0.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

0.1.0

This release

0.0.0 This release

2 release files No provenance

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