{ "info": { "author": "Kevin L. Mitchell", "author_email": "klmitch@mit.edu", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "=================================\nStep Maker Step-parsing Framework\n=================================\n\n.. image:: https://travis-ci.org/klmitch/stepmaker.svg?branch=master\n :target: https://travis-ci.org/klmitch/stepmaker\n\nThe `ansible`_ system automation tool uses, as its primary primitive,\na list of steps to execute, expressed in YAML list syntax. Each step\nis described as a dictionary, with one key indicating the actual\naction to take, along with some additional keys that describe metadata\nabout the step (such as a description) or modifiers for the step (such\nas conditional expressions). This package provides a framework for\nbuilding applications that use similar step descriptions.\n\nSteps\n=====\n\nAs mentioned above, steps consist of metadata, modifiers, and an\naction, all expressed through keys on the step dictionary. The\n``stepmaker`` package provides the abstract superclasses ``Step``,\n``Modifier``, and ``Action`` that can be extended to provide\napplication-specific step structure.\n\nThe ``Step`` class is the main class for ``stepmaker``. Implementors\nmust subclass ``Step`` and provide an implementation for the\n``validate()`` method, as well as setting the ``namespace_actions``\nand ``namespace_modifiers`` class variables. The ``metadata_keys``\nclass variable can be used to identify particular keys as metadata.\nThe ``Step`` class provides a ``parse_list()`` class method for\nparsing a list of dictionaries as step descriptions, using actions and\nmodifiers discovered in the entrypoint groups declared using\n``namespace_actions`` and ``namespace_modifiers``. Invoking the step\nis as simple as calling the ``Step`` object with an\napplication-specific context.\n\nThe ``Action`` class is an abstract superclass for step actions.\nImplementors must subclass ``Action`` and implement its ``validate()``\nand ``__call__()`` methods. The ``Action`` subclass performs the\nactual work of the step. Note that actions are classed as either\n\"eager\" or \"lazy\", controlled by the ``eager`` class variable, with\nthe default being lazy. Eager actions can be used to allow for\nincluding other files or other libraries of step actions during\nparsing by ``Step.parse_list()``.\n\nThe ``Modifier`` class is an abstract superclass for step modifiers.\nA step modifier is able to modify how the action is performed;\neverything from temporary mutations of the execution context to\nskipping the step, or even executing the action multiple times (the\n``Step.evaluate()`` method can facilitate this). Implementors must\nimplement its ``validate()`` method, and then may implement the\n``pre_call()`` and/or ``post_call()`` hook methods to perform the\nnecessary work. Implementors may also set the ``restriction`` class\nvariable to restrict which actions a modifier can be used with; the\n``before`` and ``after`` class variables provide control over the\norder with which modifiers are applied; and the ``required`` and\n``prohibited`` class variables can control which other modifiers are\nrequired or prohibited on a given step.\n\nFor full details on defining steps, see the documentation on the\n``Step``, ``Action``, and ``Modifier`` classes.\n\nUtilities\n=========\n\nA number of utilities are also made available to assist with the\ncreation of a step-driven application. For instance, the\n``validate()`` methods of the ``Step``, ``Action``, and ``Modifier``\nclasses could be implemented using the ``jsonschema`` package; the\n``jsonschema_validator()`` context manager can be used with\n``jsonschema.validate()`` to translate schema validation errors into\nmore helpful ``StepError`` exceptions, which include the \"address\" of\na step configuration error. The ``Environment`` class is a special\ndictionary-like object containing system environment variables, but\nalso includes methods for registering \"special\" translators for\nenvironment variables (e.g., the \"PATH\" environment variable could be\ntranslated into a Python list-like object using the ``SpecialList``\ntranslator), opening files relative to a working directory associated\nwith the ``Environment`` object, and even executing shell commands.\nFinally, the ``RedactedObject`` and ``RedactedDict`` classes proxy to\nother objects, but are additionally capable of masking certain\nattributes or dictionary keys; this could be used on output routines\nto ensure that sensitive data such as passwords is not exposed to the\nconsole.\n\nModifiers\n---------\n\nModifiers can inhibit the further processing of a step by raising the\n``AbortStep`` exception from their ``pre_call()`` hook method.\nModifiers can also specify a result to be returned to the step's\ncaller by passing that result to ``AbortStep``. If no result is\npassed, the result will be the special singleton ``skipped``.\n\nNote that ``post_call()`` processing of the modifier still occurs;\nraising ``AbortStep`` prevents the processing of modifiers after the\none that raised it, but the ``post_call()`` method of the raising\nmodifier, along with the ones called before, are still called with the\nresult proposed in the ``AbortStep``.\n\nAddresses and the Validator Methods\n-----------------------------------\n\nThe ``StepAddress`` class is used to express the location of a\nconfiguration item, and is used during parsing by ``Step.parse()`` and\n``Step.parse_list()`` to raise helpful errors that indicate the\nlocation of a configuration problem. These addresses are also passed\non to actions and modifiers, and can be used by the ``validate()``\nmethods to raise appropriate ``StepError`` exceptions. Additionally,\nif using the ``jsonschema`` package for validation, the\n``jsonschema_validator()`` context manager can be used to translate\nschema validation errors raised by the package into ``StepError``\nexceptions that include the address. It can be used like so::\n\n with jsonschema_validator(addr):\n jsonschema.validate(config, schema)\n\n(Note that ``jsonschema`` is *not* a dependency of ``stepmaker``. The\n``jsonschema_validator()`` function uses duck-typing to avoid needing\nto install ``jsonschema`` alongside ``stepmaker``.)\n\nRedacted Objects and Dictionaries\n---------------------------------\n\nSome data may be sensitive: an application developer may wish to\ninhibit the display of that data to the console. This data may be a\nset of variables associated with the execution context, or it may even\nbe environment variables that may contain such things as passwords.\nTo ensure that such information cannot be accidentally displayed or\nused, an implementor may choose to proxy an object or dictionary using\nthe ``RedactedObject`` and ``RedactedDict`` classes. These classes\nproxy attribute and, in the case of ``RedactedDict``, item accesses\nback to an underlying object, but can return instances of ``Redacted``\nfor certain attributes or items. By default, these classes return a\nsingleton ``redacted`` instance of ``Redacted``, which has a default\nstring representation of \"\".\n\nThe attributes and items to redact are controlled by sets of attribute\nnames or item keys. This implements a black-list policy, where only\ncertain attributes or items are redacted; to implement a white-list\npolicy, where all attributes or items are redacted except for\nspecified exceptions, wrap a set in the ``Inverter`` class; this will\ninvert the sense of membership tests.\n\nIt should be noted that the sets of attributes and items passed to\n``RedactedObject`` and ``RedactedDict`` (and ``Inverter``) are saved\ndirectly, and can be updated by processes outside of the classes.\n\nEnvironment\n-----------\n\nStep-driven applications often need at least one step capable of\nexecuting shell commands on the system, and also often need to be able\nto manipulate environment variables and open files. The ``stepmaker``\npackage provides an ``Environment`` class which provides all of this\nfunctionality in a single object. The class is a dictionary\ncontaining the environment variables for execution of system commands\n(note that this is distinct from the current contents of\n``os.environ``, though the ``Environment`` class constructor uses the\ncurrent contents of ``os.environ`` as the default environment); the\nclass also keeps track of a current working directory (which is also\ndistinct from the process's current working directory). Finally,\nspecial interpreters can be associated with environment variables,\nenabling, for instance, list-like access to the \"PATH\" environment\nvariable; a full collection of special interpreters is included, and\ndescribed below.\n\nThere are two ways to invoke a shell command using an ``Environment``\ninstance. The first is to call ``popen()`` with a string or list\ndescribing the command and its options, and a set of keyword arguments\nsuitable for passing to ``subprocess.Popen``. This will return a\n``subprocess.Popen`` instance, which may then be manipulated using the\nmethods provided by that class. The second way to invoke a shell\ncommand is to call the ``Environment``; the ``__call__()`` method is\nsimilar to the ``subprocess.run()`` function provided in Python 3\nversions of ``subprocess``, and will return a\n``stepmaker.CompletedProcess`` object with the command's return code,\nalong with captured standard output and standard error (to capture\nthese streams, pass ``subprocess.PIPE`` or ``stepmaker.PIPE`` to the\n``stdout`` and/or ``stderr`` keyword arguments to ``__call__()``).\nAdditionally, if the ``input`` keyword argument is provided, it will\nbe sent to the command's standard input; and if the ``check`` keyword\nargument is set to ``True``, a ``stepmaker.ProcessError`` exception\nwill be raised if the command's return code is non-zero. This will,\nof course, wait for process execution to complete before continuing.\n\nIn addition to ``stepmaker.PIPE``, the ``stepmaker`` package also\ncopies ``subprocess.STDOUT`` for convenience. This allows the use of\nthe ``Environment`` command execution facilities without having to\nseparately import ``subprocess``.\n\nThe ``Environment`` class tracks a working directory, which can be\nchanged by setting the ``cwd`` property. Commands are, by default,\nexecuted with there working directory set to the value of ``cwd``. It\nis also possible to locate a file relative to the ``cwd``, using the\n``filename()`` method; and the file may even be opened (using the\n``open()`` built-in) with the ``open()`` method.\n\nSpecials\n~~~~~~~~\n\nSpecials are environment variable interpreters attached to an\n``Environment`` instance. They can be registered at construction\ntime, by passing keyword arguments of the form ``VARIABLE=factory``\n(e.g., ``PATH=SpecialList``) to the constructor, or they can be\nregistered after the fact by calling the ``register()`` method of the\n``Environment``. (Specials may also be unregistered by calling\n``register()`` without a factory function.) Several specials are\nprovided, such as the ``SpecialList`` for list-like environment\nvariables, such as \"PATH\"; ``SpecialSet``, for set-like environment\nvariables (distinguished from list-like environment variables in that\nordering is not important); ``SpecialDict``, for dictionary-like\nenvironment variables containing \"key=value\" pairs; or\n``SpecialOrderedDict``, which is distinguished from ``SpecialDict`` by\nthe fact that it maintains the original key order. The ``Special``\nabstract base class can be used for constructing other specials.\n\nIt should be noted that the ``SpecialList``, ``SpecialSet``,\n``SpecialDict``, and ``SpecialOrderedDict`` classes all contain a\n``with_sep()`` class method that can be used to construct a factory\nfunction using alternate separators. If the default separators are\nnot suitable for a given application, then, instead of passing the\nclass as the factory function, pass the result of calling the class's\n``with_sep()`` class method with appropriate arguments.\n\nIt should also be noted that ``Environment`` never deletes an instance\nof a special unless a new special factory is registered (or the\nspecial is deregistered). This means that the value can be kept\noutside of the environment. In particular, it is possible to use a\n``SpecialSet`` with a ``RedactedDict`` class wrapping the\n``Environment``, so that environment variables to be redacted can be\nlisted in a particular environment variable.\n\n.. _ansible: https://www.ansible.com/\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/klmitch/stepmaker", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "stepmaker", "package_url": "https://pypi.org/project/stepmaker/", "platform": "", "project_url": "https://pypi.org/project/stepmaker/", "project_urls": { "Homepage": "https://github.com/klmitch/stepmaker" }, "release_url": "https://pypi.org/project/stepmaker/0.1.0/", "requires_dist": null, "requires_python": "", "summary": "Step Maker Step-parsing Framework", "version": "0.1.0" }, "last_serial": 3593868, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "54e9054d30c5b9728265d2ac0cb2401a", "sha256": "10f2c5ab197ffbc2842a55215644757f044ab12a8a3abcbec39fbaa5d40a80e0" }, "downloads": -1, "filename": "stepmaker-0.1.0.tar.gz", "has_sig": false, "md5_digest": "54e9054d30c5b9728265d2ac0cb2401a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41209, "upload_time": "2018-02-18T18:12:31", "url": "https://files.pythonhosted.org/packages/9d/79/f78db39a5c610e1dcd71f16e6ca7885fe8c5ade6d67e663ccb4bd0a35b60/stepmaker-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "54e9054d30c5b9728265d2ac0cb2401a", "sha256": "10f2c5ab197ffbc2842a55215644757f044ab12a8a3abcbec39fbaa5d40a80e0" }, "downloads": -1, "filename": "stepmaker-0.1.0.tar.gz", "has_sig": false, "md5_digest": "54e9054d30c5b9728265d2ac0cb2401a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41209, "upload_time": "2018-02-18T18:12:31", "url": "https://files.pythonhosted.org/packages/9d/79/f78db39a5c610e1dcd71f16e6ca7885fe8c5ade6d67e663ccb4bd0a35b60/stepmaker-0.1.0.tar.gz" } ] }