Skip to main content

Decorate class methods with shell commands

Project description

qwikfire

Release Build status codecov Commit activity License

Decorate class methods with one or more shell commands

QwikFire allows users to annotate class methods with a list of shell commands. The decorator does not execute these commands but injects an extra (hidden) QwikFire argument into the annotated method's argument list right after self. The method implementation can use the qf handle to execute all commands in the annotation using a one-liner: qf.run().

An brief example should clearly demonstrate the benefits of using the @qwikfire annotation to keep your python code clean and easy to read. The annotation executes two echo commands one after the other using Jinja style variable substitution. If an exception were to occur it will be caught, wrapped within a user defined, domain specific WrappingException which extends QwikFireException, and re-raised:

  class WrappingException(QwikFireException):
  ...
  @qwikfire(WrappingException, "echo {{hello_var}}", "echo {{world_var}}")
  def many_twovars(self, qf: QwikFire) -> str:
    return qf.run(self, hello_var="hello", world_var="world").stripped

  ...
  # invoking the method without the (hidden) QwikFire argument
  instance.many_twovars()

Callers do not include the injected hidden QwikFire argument intended for the implementation to use. Notice that no warnings arise with callers missing the QwikFire argument: i.e. instance.many_twovars().

The example above, demonstrates how almost all the boilerplate for try / except blocks, conditional checks, logging, etc, is gone. Reading and understanding what commands the method executes and what exceptions it raises makes the annotation self documenting.

QwikFire and its annotation is properly typed preventing Python typing tools (i.e pyright, pyre, mypy) from needlessly littering your code with complaint's. This is a common problem with decorators that inject additional parameters since the signature of the definition differs from the signature of callers. Overall the code is much more readable while the pattern results in pythonic OO code when chaining method outputs to other method inputs.

sh package kwargs (see https://sh.readthedocs.io/en/latest/sections/special_arguments.html#) can be used in the run() method. They're prefixed with _, and are passed through to the sh.Command. If the class whose methods are annotated, exposes a dictionary accessor method called sh_defaults(self, method: Caller[..., Any]), the values of the dictionary it returns are used for defaults both for variable substitutions and for pass-through arguments to the sh.Command. NOTE: the method is provided to, if needed, tailor defaults to specific class methods. Method specific kwarg key pairs provided to the run method override these defaults.

Why?

Even with the glorious sh package, I still find myself writing boilerplate code, logging, error handling and raising higher level (wrapper) exceptions specific to the domain of the package or application using sh. Even though sh does a great job minimizing the boilerplate, it still clutters my code, and reduces its readability. Other code maintainers will still need to know about sh and how I used it.

NOTE: Piped commands do NOT work. Use output chaining of one annotated method as input into another, if needed as a one off. Multiple semi-colon separated commands in the same string, i.e. "echo {{hello_var}}; echo {{world_var}}" will NOT work, just use separate commands in the variadic string commands array.

If you find you need these or other shell features you're probably over doing it. Write an actual shell script and execute that instead, or directly use the sh package in your code. QwikFire is purposefully meant to be simple and there to prevent the occasional shell command from cluttering up your code.


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

qwikfire-0.1.2.tar.gz (8.2 kB view details)

Uploaded Source

Built Distribution

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

qwikfire-0.1.2-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file qwikfire-0.1.2.tar.gz.

File metadata

  • Download URL: qwikfire-0.1.2.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.10 Linux/6.5.0-1025-azure

File hashes

Hashes for qwikfire-0.1.2.tar.gz
Algorithm Hash digest
SHA256 667f74f52523821019e1e2b6a647b0fba1eab8fe21e817a38f0fe1ac4fbcd495
MD5 f7daca6fd08e7200ac85de18b5111465
BLAKE2b-256 4589ca9c0371b5717063b4020d4b8118e3b3237b675f8a10228d7c078f38811f

See more details on using hashes here.

File details

Details for the file qwikfire-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: qwikfire-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.10 Linux/6.5.0-1025-azure

File hashes

Hashes for qwikfire-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8f837deba0bf0da622d7145a8305f0f5c19dae4c4a7840da6905ef0d726f8517
MD5 84b5d8f3e92990af2e88f98e0fbcea4e
BLAKE2b-256 115aaefd1d1a7351780461a21a0cac02beb7394cd1d2308a5b4072184ca40580

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