Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
AppCLI
.. AppCLI is a Python library for making command-line applications. More broadly, it's a framework for defining object properties that read their default values from arbitrary sources, e.g. the command-line, configuration files, environment variables, REST APIs, etc.
defining objects with properties that are initialized from blah blah blah sources such as the command line,
It works by (allowing|providing a framework for) objects to define parameters that are initialized|read from external sources, e.g. the command-line, configuration files, environment variables.
It works by giving classes a simple way to define parameters that will be initialized from external sources, e.g. the command-line, configuration files, environment variables, etc.
It works by providing a simple way for classes to define parameters that will be initialized from external sources, e.g. the command-line, configuration files, environment variables, etc.
Library for making command-line applications in python.
More broadly, it's a framework for creating objects with parameters that can read default values from multiple sources, e.g. the command-line, config files, environmnt variables, etc.
for defining object parameters that can query multiple sources---e.g. the command-line, configuration files, environment variables, etc.--- default parameters of an object
Benefits
Example
Can't have so many comments; makes it hard to grok.
Just want to give a sense of what it looks like.
Advanced users will want to see the syntax to get a sense of how it works.
Features to include:
cast?
default?
at least two configs
.. image:: https://img.shields.io/pypi/v/appcli.svg :target: https://pypi.python.org/pypi/appcli
.. image:: https://img.shields.io/pypi/pyversions/appcli.svg :target: https://pypi.python.org/pypi/appcli
.. image:: https://img.shields.io/readthedocs/appcli.svg :target: https://appcli.readthedocs.io/en/latest/?badge=latest
.. image:: https://img.shields.io/github/workflow/status/kalekundert/appcli/Test%20and%20release/master :target: https://github.com/kalekundert/appcli/actions
.. image:: https://img.shields.io/coveralls/kalekundert/appcli.svg :target: https://coveralls.io/github/kalekundert/appcli?branch=master
AppCLI is a Library for making command line apps. You can also think of it as
a library for initializing objects with values from disparate sources, e.g.
config files, environment variables, command-line options, etc. It's
philosophy is that (i) it should be easy to incorporate options from the
command line and config files, and (ii) the object should remain usable as a
normal object in python.
The following snippets introduce the basic concepts behind appcli
::
import appcli
from appcli import DocoptConfig, AppDirsConfig, Key
# Inheriting from App will give us the ability to instantiate MyApp objects
# without calling the constructor, i.e. exclusively using information from
# the command-line and the config files. We'll take advantage of this in
# the '__main__' block at the end of the script:
class MyApp(appcli.App):
"""
Do a thing.
Usage:
myapp <x> [-y]
"""
# The `__config__` class variable defines locations to search for
# parameter values. In this case, we specify that `docopt` should be
# used to parse command line arguments, and that `appdirs` should be
# used to find configuration files. Note however that appcli is not
# tied to any particular command-line argument parser or file format.
# A wide variety of `Config` classes come with `appcli`, and it's also
# easy to write your own.
__config__ = [
DocoptConfig(),
AppDirsConfig(),
]
# The `appcli.param()` calls define attributes that will take their
# value from the configuration source specified above. For example,
# the `x` parameter will look for an argument named `<x>` specified on
# the command line. The `y` parameter is similar, but will also (i)
# look for a value in the configuration files if none if specified on
# the command line, (ii) convert the value to an integer, and (iii) use
# a default of 0 if no other value is found.
x = appcli.param(
Key(DocoptConfig, '<x>'),
)
y = appcli.param(
Key(DocoptConfig, '-y'),
Key(AppDirsConfig, 'y'),
cast=int,
default=0,
)
# Define a constructor because we want this object to be fully usable
# from python. Because <x> is a required argument on the command line,
# it makes sense for it to be a required argument to the constructor as
# well.
def __init__(self, x):
self.x = x
# Define one or more methods that actually do whatever this application
# is supposed to do. These methods can be named anything; think of
# MyApp as a totally normal class by this point. Note that `x` and `y`
# can be used exactly like regular attributes.
def main(self):
return self.x * self.y
# Invoke the application from the command line. Note that we can't call
# the constructor because it requires an `x` argument, and we don't have
# that information yet (because it will come from the command line).
# Instead we use the `from_params()` method provided by `appcli.App`. This
# constructs an instance of MyApp without calling the construtor, instead
# depending fully on the command-line and the configuration files to
# provide values for every parameter. The call to `appcli.load()` triggers
# the command line to be parsed, such that the `app` instance is fully
# initialized when the `main()` method is called.
if __name__ == '__main__':
app = Main.from_params()
appcli.load(app)
app.main()
Note that we could seamlessly use this object in another python script::
from myapp import MyApp
# Because we don't call `appcli.load()` in this script, the command line
# would not be parsed. The configuration files would still be read,
# however. In the snippet below, for example, the value of `app.y` could
# come from the configuration file. See `Config.autoload` for more
# information on controlling which configs are used in which contexts.
app = MyApp('abc')
app.main()
For some examples of appcli
being used in real scripts, check out the
Stepwise — Molecular Biology
__ repository. Almost every script in this
repository uses appcli
. Below are some particular scripts that might be
useful:
Simple scripts:
aliquot.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/aliquot.py>
_anneal.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/anneal.py>
_kld.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/kld.py>
_Long but straight-forward scripts:
pcr.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/pcr.py>
_spin_cleanup.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/spin_cleanup.py>
_gels/gel.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/gels/gel.py>
_gels/stain.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/gels/stain.py>
_Complex scripts:
serial_dilution.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/serial_dilution.py>
_
This script features parameters that depend on other parameters.
Specifically, the user must provide values for any three of volume
,
conc_high
, conc_low
, and factor
. Whichever one isn't specified
is inferred from the ones that are. This is implemented by making the
appcli
parameters (which in this case read only from the command-line and
not from any config files) private, then adding public properties that are
calculated from the private ones.
digest.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/digest.py>
_
This script is actually pretty simple, but it makes used of
__bareinit__()
to download some data from the internet. As alluded to
above, __init__()
is not called when App
instances are initialized
from the command-line, because __init__()
might require arbitrary
arguments and is therefore considered to be part of the python API. Instead,
App
instances are initialized by calling __bareinit__()
with no
arguments.
ivtt.py <https://github.com/kalekundert/stepwise_mol_bio/blob/master/stepwise_mol_bio/ivtt.py>
_
This script defines a custom Config
class to read from a sequence
database. (This example might go out of date, though; I have plans to move
that custom Config
into a different package.)
FAQs
An object-oriented framework for command-line apps.
We found that appcli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.