Working with shell programs in Python made easier.
Project description
python-shell-cmd-wrapper
Based on one of the parts of my bachelor thesis testing framework. Enables to call shell programs seamlessly within Python workflow. Derived from my bachelor thesis.
Motivation
Whilst working with not very widespread libraries/commands one might struggle using them without proper Python wrapper. Oftentimes nothing fancy is really required, simple abstraction layer is all that is needed. I encountered this very problem in my bachelor thesis when trying to automate image compression pipeline (JPEG2000) using various libraries. This package builds abstraction layer over base set of libraries, at the same time enabling users to easily add new ones.
Installation
pip install pyshellwrapper
Requires Python >=3.7
.
Introductory Notes
-
Typical CLI use certain naming convension for prompt values.
wget google.com -o log.txt
wget
is a command,google.com
is a parameter and-o
is switch/flag. In this package, everything is considered to be a flag. -
Every library is controlled by a special type of
json
document calledblueprint
. There, each flag is described and is used as foundation for flag transformation. Structure is going to discussed later. -
There are three type of flags:
fixed
,variable
,auxiliary
. Fixed flags are constant throughout program cycle (input file or logging), variable are meant to be changed (output file or color profile) and auxiliary are simple appended at the end without any transformation. Program cycle is denoted by callingconstruct()
method; it can also be tweaked, more on that later. Default behavior is to callset_fixed()
once since all flags are directly transformed to output format. However it is possible to callset_fixed
multiple times in program cycle if each flag is set only once, otherwiseValueError
is raised. Variable flags are set byset_variable()
in the same manner or list/tuple can be used to specify all options from one place.
Blueprint
Used for describing flags/parameters of a command. Each blueprint has two mandatory items: settings
and flags
.
{
"settings": {
"required_flags": [
"input", "output"
],
"libraries" : [
"kdu_compress", "opj_compress"
]
}
}
Here is a typical settings
portion of a blueprint. First are required_flags
. Most of the programs have at least one so it is logical to require specification to avoid unnecessary error at execution. libraries
are used for distinguishing between multiple libraries in single blueprint. This is optional and only required for multiple libraries.
{
"flags": {
"input": [
{
"flag" : "-i",
"unifier" : null,
"format" : {
"number" : 1,
"preset": "1"
}
},
{
"flag" : "-i",
"unifier" : null,
"format" : {
"number" : 1,
"preset": "1"
}
}
],
}
}
Individual flags
have following structure. Flag name can by selected at user's will; semantic meaning is advised to be preserved. Its value is array for multiple options, this structure is unchanged not matter how many libraries is there to maintain consistency. This example would take input="path/to/file"
and transform it to -i /path/to/file
. Sometimes naming of a flag is not needed. If further manipulation of given flag is desired (variable) set "flag": null
, otherwise use set_auxiliary()
. Flag can have parameters that are paired by location (directly follows) -flag param
or by certain unifier -flag=param
. Format specifies flag parameter; count
is used for transformation purposes, preset
are predefined format for user convenience.
Preset | Input | Transformed |
---|---|---|
1 | input="input.txt" | -i input.txt |
2, | point=(20,45) | --point 20,45 |
[2,] | point=(20,45) | --point [20,45] |
(2,) | point=(20,45) | --point (20,45) |
{2,} | point=(20,45) | --point {20,45} |
User defined formats presets are comming in next version (0.2
).
Number vs. List
Distinction might be unclear. number
is a number of parameter's parts that constitute compoment. Input file always has one part (file name), point in 2D space have 2 x,y
and so on. Parameter can consist of multiple compoment, e.g. start points for a game --points=[0,0],[50,20],[880,50]
. Therefore list
is a list of components that are composed of parts (with given number).
{
"points": [
{
"flag" : "--points",
"unifier" : "=",
"format" : {
"number" : 2,
"preset": "[2,]"
},
"list": {
"divider": ","
}
}
]
}
Example of points
flag. Please note list
are to be fully supported in version (0.3
)
Basic usage
Lib
class
Let us look onto basic usage with predefined library (wget
). Lib
is main class of package wrapping functionality. blueprint
refers to json file in ./blueprint
.
convert_lib = Lib(
blueprint='convert'
)
Each blueprint might contain more than one library, lib
distinguishes particular library. Sometimes one might want to repeat construction of flags for more advanced usage, default behaviour is to discard set flags.
compress = Lib(
blueprint='compress_libs',
lib='kdu_compress',
reset_after_construct=True
)
Adding flags
Setting fixed flags is advised to only once per each construction (if reset_after_construct
is True
) because once this method is invoked it automatically transforms all flags and stores them internally for faster construction. Repeated use might raise performance concerns for large number of flags.
convert_lib.set_fixed(
colorspace='rgb'
)
convert_lib.set_variable(
resize=[10, 20, 30, 50, 90]
)
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
Built Distribution
Hashes for pyshellwrapper-0.1.4-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8c1d1348afcd5a0852645f88e7d12d6081a51f6d8e09433f72a09ba99367a0f9 |
|
MD5 | 66e6d5ea367ed31396b136ae1de8cdf0 |
|
BLAKE2b-256 | 506236213f59db3e4846b608fa48b59c2a8fcdff9c9b9dcb481521ac0fda1f46 |