{ "info": { "author": "Rudolph Pienaar", "author_email": "rudolph.pienaar@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "###################\npfstate v1.1.1.2\n###################\n\n.. image:: https://badge.fury.io/py/pfstate.svg\n :target: https://badge.fury.io/py/pfstate\n\n.. image:: https://travis-ci.org/FNNDSC/pfstate.svg?branch=master\n :target: https://travis-ci.org/FNNDSC/pfstate\n\n.. image:: https://img.shields.io/badge/python-3.5%2B-blue.svg\n :target: https://badge.fury.io/py/pfcon\n\n.. contents:: Table of Contents\n\n********\nOverview\n********\n\nThis 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.\n\npfstate\n=======\n\nMost 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.\n\nMoreover, 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.\n\nBy 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. \n\nIn some ways, this can be thought of a cleaner way to avoid using a global variable.\n\nConsult 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.\n\nNote, 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.\n\n.. code-block:: python\n\n from pfmisc.C_snode import C_snode\n from pfmisc._colors import Colors\n from pfstate import S\n from argparse import RawTextHelpFormatter\n from argparse import ArgumentParser\n\n str_desc = \"some program description\"\n str_version = \"1.0.0.0\"\n\n parser = ArgumentParser(\n description = str_desc, \n formatter_class = RawTextHelpFormatter\n )\n\n parser.add_argument(\n '--msg',\n action = 'store',\n dest = 'msg',\n default = '',\n help = 'Message payload for internalctl control.'\n )\n\n class D(S):\n \"\"\"\n A derived class with problem-specific state\n \"\"\"\n\n def __init__(self, *args, **kwargs):\n \"\"\"\n Constructor\n \"\"\"\n S.__init__(self, *args, **kwargs)\n if not S.b_init:\n d_specific = \\\n {\n 'specificState': {\n 'desc': 'Additional state information',\n 'theAnswer': 42,\n 'theQuestion': 'What do you get if you multiple six by nine',\n 'foundBy': 'Arthur Dent'\n },\n 'earthState': {\n 'current': 'Destroyed',\n 'reason': 'Hyper space bypass',\n 'survivors': {\n 'humans': ['Arthur Dent', 'Ford Prefect', 'Trillian'],\n 'dolphins': 'Most of them'\n }\n }\n }\n S.d_state.update(d_specific)\n S.T.initFromDict(S.d_state)\n S.b_init = True\n if len(S.T.cat('/this/debugToDir')):\n if not os.path.exists(S.T.cat('/this/debugToDir')):\n os.makedirs(S.T.cat('/this/debugToDir'))\n\n self.dp.qprint(\n Colors.YELLOW + \"\\n\\t\\tInternal data tree:\", \n level = 1,\n syslog = False)\n self.dp.qprint(\n C_snode.str_blockIndent(str(S.T), 3, 8), \n level = 1,\n syslog = False)\n\n state = D( \n version = str_version,\n desc = str_desc,\n args = vars(args)\n )\n\n if len(args.msg):\n d_control = state.internalctl_process(request = json.loads(args.msg))\n print(\n json.dumps(\n d_control,\n indent = 4\n )\n )\n\n************\nInstallation\n************\n\nInstallation is relatively straightforward, and we recommend using python ```pip`` to simplu install the module, preferably in a python virtual environment.\n\nPython Virtual Environment\n==========================\n\nOn Ubuntu, install the Python virtual environment creator\n\n.. code-block:: bash\n\n sudo apt install virtualenv\n\nThen, create a directory for your virtual environments e.g.:\n\n.. code-block:: bash\n\n mkdir ~/python-envs\n\nYou might want to add to your .bashrc file these two lines:\n\n.. code-block:: bash\n\n export WORKON_HOME=~/python-envs\n source /usr/local/bin/virtualenvwrapper.sh\n\nNote that depending on distro, the virtualenvwrapper.sh path might be\n\n.. code-block:: bash\n\n /usr/share/virtualenvwrapper/virtualenvwrapper.sh\n\nSubsequently, you can source your ``.bashrc`` and create a new Python3 virtual environment:\n\n.. code-block:: bash\n\n source .bashrc\n mkvirtualenv --python=python3 python_env\n\nTo activate or \"enter\" the virtual env:\n\n.. code-block:: bash\n\n workon python_env\n\nTo deactivate virtual env:\n\n.. code-block:: bash\n\n deactivate\n\nInstall the module\n\n.. code-block:: bash\n \n pip install pfstate\n\n\nUsing the ``fnndsc/pfstorage`` docker container\n================================================\n\nFor 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.\n\n*****\nUsage\n*****\n\nFor usage of ``pstate``, consult the relevant wiki pages `.\n\n\nCommand line arguments\n======================\n\n.. code-block:: html\n\n [--msg '']\n An optional JSON formatted string exemplifying how to get and\n set internal variables.\n \n --msg '\n { \n \"action\": \"internalctl\",\n \"meta\": {\n \"var\": \"/\",\n \"get\": \"value\"\n }\n }'\n\n --msg '\n { \"action\": \"internalctl\",\n \"meta\": {\n \"var\": \"/service/megalodon\",\n \"set\": {\n \"compute\": {\n \"addr\": \"10.20.1.71:5010\",\n \"baseURLpath\": \"api/v1/cmd/\",\n \"status\": \"undefined\"\n },\n \"data\": {\n \"addr\": \"10.20.1.71:5055\",\n \"baseURLpath\": \"api/v1/cmd/\",\n \"status\": \"undefined\"\n }\n }\n }\n }'\n\n [--configFileLoad ]\n Load configuration information from the JSON formatted .\n\n [--configFileSave ]\n Save configuration information to the JSON formatted .\n\n [-x|--desc] \n Provide an overview help page.\n\n [-y|--synopsis]\n Provide a synopsis help summary.\n\n [--version]\n Print internal version number and exit.\n\n [--debugToDir ]\n A directory to contain various debugging output -- these are typically\n JSON object strings capturing internal state. If empty string (default)\n then no debugging outputs are captured/generated. If specified, then\n ``pfcon`` will check for dir existence and attempt to create if\n needed.\n\n [-v|--verbosity ]\n Set the verbosity level. \"0\" typically means no/minimal output. Allows for\n more fine tuned output control as opposed to '--quiet' that effectively\n silences everything.\n\nEXAMPLES\n\n.. code-block:: bash\n\n pfstate \\\\\n --msg ' \n { \"action\": \"internalctl\",\n \"meta\": {\n \"var\": \"/\",\n \"get\": \"value\"\n }\n }'", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/FNNDSC/pfstate", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "pfstate", "package_url": "https://pypi.org/project/pfstate/", "platform": "", "project_url": "https://pypi.org/project/pfstate/", "project_urls": { "Homepage": "https://github.com/FNNDSC/pfstate" }, "release_url": "https://pypi.org/project/pfstate/1.1.1.2/", "requires_dist": null, "requires_python": "", "summary": "class-defintion stateful module", "version": "1.1.1.2" }, "last_serial": 5783483, "releases": { "1.0.0.0": [ { "comment_text": "", "digests": { "md5": "8a461f55d5c2bdca554393ac2d283126", "sha256": "8162a48321e43bddde2a6db172ae4c448b2cb3d639520f246002d93073dac34c" }, "downloads": -1, "filename": "pfstate-1.0.0.0.tar.gz", "has_sig": false, "md5_digest": "8a461f55d5c2bdca554393ac2d283126", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11383, "upload_time": "2019-08-22T16:57:20", "url": "https://files.pythonhosted.org/packages/81/87/2c08ace867e75045c224b62613d3d55a6e5699c5ced27724cdbc0870f41c/pfstate-1.0.0.0.tar.gz" } ], "1.0.1.0": [ { "comment_text": "", "digests": { "md5": "fce5b54d919c9cf5457705a6c47351e7", "sha256": "723780a358bbbabc93a724899a5df13f8a47533c2031e6335038382a8992abd9" }, "downloads": -1, "filename": "pfstate-1.0.1.0.tar.gz", "has_sig": false, "md5_digest": "fce5b54d919c9cf5457705a6c47351e7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11673, "upload_time": "2019-08-27T20:50:47", "url": "https://files.pythonhosted.org/packages/b8/50/212f317f9ca10eb463dca11f0248a575a72e2f85b8a1d9f90a1bc4484c90/pfstate-1.0.1.0.tar.gz" } ], "1.0.1.2": [ { "comment_text": "", "digests": { "md5": "59954296d30ab0e33df076911ce1909c", "sha256": "25f38fef83c9bf3456bd5e423f44d9250ed8205906d748b081980e11923a118b" }, "downloads": -1, "filename": "pfstate-1.0.1.2.tar.gz", "has_sig": false, "md5_digest": "59954296d30ab0e33df076911ce1909c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11673, "upload_time": "2019-09-03T18:09:15", "url": "https://files.pythonhosted.org/packages/03/39/fac6c1d497f28673e8ab83c765b9858bc1ddd7e9b96aafdc7a0ac19b3f4f/pfstate-1.0.1.2.tar.gz" } ], "1.1.1.2": [ { "comment_text": "", "digests": { "md5": "b4f11056e433ab3ff63df6b3f64e26a8", "sha256": "f1dd056f3dc4c2fac98e4fee301998a6a318f5396d7514470d73cbcbd6172c2a" }, "downloads": -1, "filename": "pfstate-1.1.1.2.tar.gz", "has_sig": false, "md5_digest": "b4f11056e433ab3ff63df6b3f64e26a8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11679, "upload_time": "2019-09-04T21:06:40", "url": "https://files.pythonhosted.org/packages/ac/4a/4b7aa7bd4b97a237e348030d4054194ca06c6c3e01b652edc77222bbdaf5/pfstate-1.1.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "b4f11056e433ab3ff63df6b3f64e26a8", "sha256": "f1dd056f3dc4c2fac98e4fee301998a6a318f5396d7514470d73cbcbd6172c2a" }, "downloads": -1, "filename": "pfstate-1.1.1.2.tar.gz", "has_sig": false, "md5_digest": "b4f11056e433ab3ff63df6b3f64e26a8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11679, "upload_time": "2019-09-04T21:06:40", "url": "https://files.pythonhosted.org/packages/ac/4a/4b7aa7bd4b97a237e348030d4054194ca06c6c3e01b652edc77222bbdaf5/pfstate-1.1.1.2.tar.gz" } ] }