Skip to main content
Join the official 2020 Python Developers SurveyStart the survey!

class-defintion stateful module

Project description

https://badge.fury.io/py/pfstate.svg https://travis-ci.org/FNNDSC/pfstate.svg?branch=master https://img.shields.io/badge/python-3.5%2B-blue.svg

Overview

This repository provides pfstate – a library / module that maintains state in the object/class definition (and not in a class instance). The module uses the tree C_snode data abstraction internally (see elsewhere for C_snode) as well as some internal methods to set/get this internal data in various ways.

pfstate

Most simply, pfstate is a module that keeps state in a class definition (as opposed to a class instance). It was primarily created in the context of custom ThreadedHTTPServer classes. Creating a ThreadedHTTPServer in python involves instantiating the ThreadedHTTPServer, and in the constructor providing a derived BaseHTTPRequestHandler object. The design pattern has some structural shortcomings – most notably that the difficulty in setting internal BaseHTTPRequestHandler data from the level of the ThreadedHTTPServer. One mechanism to overcome this is to share a common single pfstate object across the scope of both the server and the handler.

Moreover, each call to the ThreadedHTTPServer re-initializes the handler object derived from BaseHTTPRequestHandler, so any state information in that object instance is lost across calls.

By using the pfstate module, however, in the handler object, state information can be preserved across calls to the ThreadedHTTPServer by keeping state in the object and not an instance of the object.

In some ways, this can be thought of a cleaner way to avoid using a global variable.

Consult the source code for full detail. However, as a simple overview, the recommended method of using this module is to define a subclass containing the state-specific information in a dictionary, and then to initialize the class.

Note, it is vitally important that this derived class check the initialization of the base object data so as to not re-initialize an already stateful object and hence lose any additional state information.

from    pfmisc.C_snode      import C_snode
from    pfmisc._colors      import Colors
from    pfstate             import S
from    argparse            import RawTextHelpFormatter
from    argparse            import ArgumentParser

str_desc        = "some program description"
str_version     = "1.0.0.0"

parser          = ArgumentParser(
                    description = str_desc,
                    formatter_class = RawTextHelpFormatter
                )

parser.add_argument(
    '--msg',
    action  = 'store',
    dest    = 'msg',
    default = '',
    help    = 'Message payload for internalctl control.'
)

class D(S):
    """
    A derived class with problem-specific state
    """

    def __init__(self, *args, **kwargs):
        """
        Constructor
        """
        S.__init__(self, *args, **kwargs)
        if not S.b_init:
            d_specific  = \
                {
                    'specificState': {
                        'desc':         'Additional state information',
                        'theAnswer':    42,
                        'theQuestion':  'What do you get if you multiple six by nine',
                        'foundBy':      'Arthur Dent'
                    },
                    'earthState': {
                        'current':      'Destroyed',
                        'reason':       'Hyper space bypass',
                        'survivors': {
                            'humans':   ['Arthur Dent', 'Ford Prefect', 'Trillian'],
                            'dolphins': 'Most of them'
                        }
                    }
                }
            S.d_state.update(d_specific)
            S.T.initFromDict(S.d_state)
            S.b_init    = True
            if len(S.T.cat('/this/debugToDir')):
                if not os.path.exists(S.T.cat('/this/debugToDir')):
                    os.makedirs(S.T.cat('/this/debugToDir'))

        self.dp.qprint(
            Colors.YELLOW + "\n\t\tInternal data tree:",
            level   = 1,
            syslog  = False)
        self.dp.qprint(
            C_snode.str_blockIndent(str(S.T), 3, 8),
            level   = 1,
            syslog  = False)

state   = D(
    version     = str_version,
    desc        = str_desc,
    args        = vars(args)
)

if len(args.msg):
    d_control = state.internalctl_process(request = json.loads(args.msg))
    print(
        json.dumps(
            d_control,
            indent = 4
        )
    )

Installation

Installation is relatively straightforward, and we recommend using python `pip to simplu install the module, preferably in a python virtual environment.

Python Virtual Environment

On Ubuntu, install the Python virtual environment creator

sudo apt install virtualenv

Then, create a directory for your virtual environments e.g.:

mkdir ~/python-envs

You might want to add to your .bashrc file these two lines:

export WORKON_HOME=~/python-envs
source /usr/local/bin/virtualenvwrapper.sh

Note that depending on distro, the virtualenvwrapper.sh path might be

/usr/share/virtualenvwrapper/virtualenvwrapper.sh

Subsequently, you can source your .bashrc and create a new Python3 virtual environment:

source .bashrc
mkvirtualenv --python=python3 python_env

To activate or “enter” the virtual env:

workon python_env

To deactivate virtual env:

deactivate

Install the module

pip install pfstate

Using the fnndsc/pfstorage docker container

For completeness sake with other pf* packages, a dockerized build is provided, although its utility is debatable and running / building the docker image will serve little purpose.

Usage

For usage of pstate, consult the relevant wiki pages <https://github.com/FNNDSC/pfstate/wiki/pfstate-overview>`.

Command line arguments

[--msg '<JSON_formatted>']
An optional JSON formatted string exemplifying how to get and
set internal variables.

--msg '
{
    "action": "internalctl",
    "meta": {
                "var":     "/",
                "get":      "value"
            }
}'

--msg '
{   "action": "internalctl",
    "meta": {
                "var":     "/service/megalodon",
                "set":     {
                    "compute": {
                        "addr": "10.20.1.71:5010",
                        "baseURLpath": "api/v1/cmd/",
                        "status": "undefined"
                    },
                    "data": {
                        "addr": "10.20.1.71:5055",
                        "baseURLpath": "api/v1/cmd/",
                        "status": "undefined"
                    }
                }
            }
}'

[--configFileLoad <file>]
Load configuration information from the JSON formatted <file>.

[--configFileSave <file>]
Save configuration information to the JSON formatted <file>.

[-x|--desc]
Provide an overview help page.

[-y|--synopsis]
Provide a synopsis help summary.

[--version]
Print internal version number and exit.

[--debugToDir <dir>]
A directory to contain various debugging output -- these are typically
JSON object strings capturing internal state. If empty string (default)
then no debugging outputs are captured/generated. If specified, then
``pfcon`` will check for dir existence and attempt to create if
needed.

[-v|--verbosity <level>]
Set the verbosity level. "0" typically means no/minimal output. Allows for
more fine tuned output control as opposed to '--quiet' that effectively
silences everything.

EXAMPLES

pfstate                                                \\
    --msg '
        {  "action": "internalctl",
            "meta": {
                        "var":     "/",
                        "get":      "value"
                    }
        }'

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for pfstate, version 1.1.1.2
Filename, size File type Python version Upload date Hashes
Filename, size pfstate-1.1.1.2.tar.gz (11.7 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page