{ "info": { "author": "Peter A. Donis", "author_email": "peterdonis@alum.mit.edu", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Environment :: MacOS X", "Environment :: Win32 (MS Windows)", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "The PLIB3.IO package contains classes that encapsulate various forms\nof client/server I/O channels.\n\nNote: PLIB3.IO works with Python 3. If you are using Python\n2.7, see the PLIB.IO package, available at\nhttps://pypi.org/project/plib.io.\n\nThe ``setup.py`` script for PLIB3.IO uses the ``setuputils``\nhelper module, which helps to automate away much of the\nboilerplate in Python setup scripts. This module is available\nas a separate release at https://pypi.org/project/setuputils3.\n\nThe PLIB3.IO Packages and Modules\n---------------------------------\n\nThe ``comm`` sub-package provides utilities for managing and\ncommunicating with child threads and processes. This is shipped\nas a separate ``plib`` sub-package from ``io``, so it can be\nused independently of the ``io`` code.\n\nThe ``base`` sub-package contains base classes that implement\ncommon basic functionality that is built on by the rest of PLIB3.IO.\n\nMost of the remaining sub-packages fall into four main categories:\n\n- **Device Types**: ``socket`` and ``serial``. Each device type has\n a ``BaseClient`` and ``BaseServer`` class; the ``socket`` type\n also has a ``BaseRequest`` class. These will usually not need to\n be used directly; they are used by the I/O mode classes, and are\n factored out so that each I/O mode sees the same API for a given\n device type.\n\n- **Channel Types**: The ``comm`` sub-package contains classes that\n implement the basic functionality of the three types of I/O\n channels: clients, servers, and \"persistent\" (the latter is only\n available with the nonblocking I/O mode--see below). Each I/O mode\n then builds on these base classes to implement its specific channels.\n\n- **I/O modes**: ``nonblocking`` and ``blocking`` (the latter does not\n just mean synchronous: it includes a forking TCP socket server). Each\n I/O mode has a client and server class for both device types, and\n a request class for the ``socket`` device type: the class names are\n ``SerialClient``, ``SerialServer``, ``SocketClient``, ``SocketServer``,\n and ``BaseRequestHandler``. The ``nonblocking`` type also has \"persistent\"\n classes, which support full-duplex asynchronous communication; these\n are the ``PersistentSerial``, ``PersistentSocket``, and\n ``PersistentRequestHandler`` classes. Mixin versions of these classes\n (class names with ``Mixin`` at the end) are also provided, for use\n if alternate data handling is desired (see next bullet), but it is\n normally not necessary to use these \"by hand\"--see \"automatic mixins\"\n below.\n\n- **Data Handling**: the I/O mode classes given above include basic\n data handling, but it is *very* basic: the only way it can detect\n that a \"message\" has been fully received is to detect a closed\n channel. For some applications this is enough, but often more\n sophisticated and robust data handling is needed. The ``data``\n sub-package provides three mixin classes for this purpose,\n ``ShutdownReadWrite``, ``TerminatorReadWrite`` and ``ReadWrite``.\n The first of these detects the end of a received message by a\n shutdown of the other end of the data channel, but keeps the channel\n open to allow further writes (all the other classes default to\n closing the channel when the other end closes). The other two\n classes allow the detection of multiple \"messages\" in the data\n stream, either by detecting a \"terminator\" string or by having\n each message include its length at the beginning. These classes\n also format outgoing messages the same way.\n\nThere is also a ``mixins`` sub-package containing classes that\nare used as mixins by the other sub-packages, and a ``classes``\nsub-package containing higher-level classes that use the API.\nFinally, there is a ``utils`` module that implements the automatic\nmixin functionality described below.\n\nAutomatic Mixins\n~~~~~~~~~~~~~~~~\n\nTo derive your own client or server classes with alternate data\nhandling \"by hand\", you would need to use the \"mixin\" versions of\nthe appropriate I/O mode classes, and splice the data handling\nclass into the middle of the base class list; for example::\n\n from plib.io.nonblocking import SerialClientMixin, SerialBase\n from plib.io.data import TerminatorReadWrite\n \n class AsyncSerialClientWithTerminator(SerialClientMixin,\n TerminatorReadWrite, SerialBase): pass\n\nThis is a bit clumsy, but necessary since the read/write handling has\nto be *before* the client/server class in the MRO, but *after* the\nbase device type, for the cooperative ``super`` calls that underlie\nthe functionality to work properly. However, since the pattern is the\nsame in each case, it can be automated, and this has been done in the\n``nonblocking`` and ``blocking`` sub-package namespaces, so that instead\nof doing the above class construction \"by hand\", you can just append a\nsuffix to your desired class name, thus::\n\n from plib.io.nonblocking import SerialClientWithTerminator\n\nThe ``WithTerminator`` suffix (or, alternately, ``WithShutdown``\nor ``WithReadWrite``) will cause the equivalent of the above class\ndefinition to occur on the fly, so that the resulting class appears\nin the ``plib.io.nonblocking`` namespace (of course the\n``plib.io.blocking`` namespace has the same capability).\nOnce this has happened the first time, however, the class definition\nis stored in the appropriate namespace, so additional imports of the\nsame class name (in different modules of your application) will not\nre-do the \"on the fly\" construction; they will just retrieve the\nsame class object that was previously constructed.\n\nThe above machinery is also made available for use with your own custom\nread/write handling classes; the ``nonblocking`` and ``blocking``\nsub-packages each export a ``get_readwrite_class`` function that does the\nsame on-the-fly class definition as above, but with your custom read/write\nclass instead of one of the built-in ones. All you have to do is pass\nthe function the name of your desired I/O class and your custom\nread/write class object::\n\n from plib.io import nonblocking\n \n class CustomReadWrite(object):\n # class definition\n \n MyAsyncSerialClient = nonblocking.get_readwrite_class('SerialClient',\n CustomReadWrite)\n\n*API Notes*: One of the goals of this sub-package is to provide a\ncommon, consistent API for all the different types of I/O, so that\nswitching one specific implementation of a certain functionality\nfor another can be done transparently to the rest of your application's\ncode. Thus, all of the usable classes follow the same basic pattern of\nmixing in the various pieces of functionality: from left to right\nin a class's MRO, one finds the type of endpoint (a client or\nserver mixin class, which may be specialized to the type of I/O),\nthe type of data formatting, if any (a mixin class from the\n``ReadWrite`` module), and the type of I/O, including device type\n(socket, serial port, etc.), mode (non-blocking/asynchronous vs.\nblocking), and basic data handling. Also, each endpoint type has\na common API independent of the specific type of I/O and mode; a\nclient can always use the ``client_communicate`` method to send\ndata to the server and receive a response; a server can always use\nthe ``serve_forever`` method to start itself; and all I/O objects\noverride the same methods to implement application-specific\nfunctionality: ``process_data``, to deal with data as it comes in,\nand ``query_done``, to determine when the I/O channel should be\nclosed. (To see examples of all this in action, look at the test\nsuite in ``test_io.py`` and the library module for it,\n``io_testlib.py``; the library module can use the same\nmixin classes to implement test functionality for *all* of the\ndifferent mixes of I/O classes in the test suite.)\n\nInstallation\n------------\n\nTo install PLIB3.IO, you can simply run::\n\n $ python setup.py install\n\nat a shell prompt from the directory into which you\nunzipped the source tarball (the same directory that this\nREADME file is in). This will install PLIB3 and then\nrun each of the post-install scripts in the scripts\ndirectory.\n\nExample Programs\n----------------\n\nPLIB3.IO comes with example programs that illustrate key features\nof the package. After installation, these can be found in the\n``$PREFIX/share/plib/examples`` directory. If you have a\nPOSIX system (Linux or Mac OSX), the ``plib-setup-examples``\npost-install script will install symlinks to the example\nprograms in the ``$PREFIX/bin`` directory.", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.org/project/plib3.io", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "plib3.io", "package_url": "https://pypi.org/project/plib3.io/", "platform": "", "project_url": "https://pypi.org/project/plib3.io/", "project_urls": { "Homepage": "http://pypi.org/project/plib3.io" }, "release_url": "https://pypi.org/project/plib3.io/0.10.4/", "requires_dist": null, "requires_python": "", "summary": "Flexible handling of I/O channels.", "version": "0.10.4" }, "last_serial": 5901304, "releases": { "0.10": [ { "comment_text": "", "digests": { "md5": "39e2e8de0022725b1e7ce5573ac87e1c", "sha256": "92d9b89e51d5c091fe6ab60155ecc586ed675a45e54ac02baf27ec0be928c5fd" }, "downloads": -1, "filename": "plib3.io-0.10.tar.gz", "has_sig": false, "md5_digest": "39e2e8de0022725b1e7ce5573ac87e1c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 111405, "upload_time": "2019-09-23T08:07:11", "url": "https://files.pythonhosted.org/packages/90/23/f5c378b9e6e9887205dae2f01d139b1cb8b1700859af149e52329affa0fc/plib3.io-0.10.tar.gz" } ], "0.10.1": [ { "comment_text": "", "digests": { "md5": "1a4a2160975df2a744a74b888951edab", "sha256": "518c9886248bb97b7bfb1261c8766b4a648474bad55c8c90dc555c6eec9088a2" }, "downloads": -1, "filename": "plib3.io-0.10.1.tar.gz", "has_sig": false, "md5_digest": "1a4a2160975df2a744a74b888951edab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 111607, "upload_time": "2019-09-26T04:33:53", "url": "https://files.pythonhosted.org/packages/42/f7/22c064aa2f2672881aaef8283a075ed0864ccc42f9930b70beef2929d6e5/plib3.io-0.10.1.tar.gz" } ], "0.10.2": [ { "comment_text": "", "digests": { "md5": "26dcfa963396796722ed3d1187679a60", "sha256": "b595a3af9229df1cd3c87bd1af765af66aa42c8de04c7a201c45a7710722f9db" }, "downloads": -1, "filename": "plib3.io-0.10.2.tar.gz", "has_sig": false, "md5_digest": "26dcfa963396796722ed3d1187679a60", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 111882, "upload_time": "2019-09-26T17:45:31", "url": "https://files.pythonhosted.org/packages/54/12/5287c4c666534c1a94233e718493c9419be9403cd334f09124e56cabae8a/plib3.io-0.10.2.tar.gz" } ], "0.10.4": [ { "comment_text": "", "digests": { "md5": "e571eb222aba57480d7500f679eb3c39", "sha256": "a594a47d774079d1509fd44ec7d5c4dd9bc8de36aad226b12cdbacfeed038bfc" }, "downloads": -1, "filename": "plib3.io-0.10.4.tar.gz", "has_sig": false, "md5_digest": "e571eb222aba57480d7500f679eb3c39", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 112057, "upload_time": "2019-09-29T02:53:10", "url": "https://files.pythonhosted.org/packages/b2/cd/fc37ee0bf273f969dbf5b401d54ffe4b9479720e51a8cac1936f71516439/plib3.io-0.10.4.tar.gz" } ], "0.10.post1": [ { "comment_text": "", "digests": { "md5": "8cf6955981e063871fb15e1ac2ae3226", "sha256": "cf551bb24662dcf5fc7109dfa2f8b609550625dc00f1b3f99530ea9c5ba1a877" }, "downloads": -1, "filename": "plib3.io-0.10.post1.tar.gz", "has_sig": false, "md5_digest": "8cf6955981e063871fb15e1ac2ae3226", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 111422, "upload_time": "2019-09-23T16:59:33", "url": "https://files.pythonhosted.org/packages/68/3c/d1d95445e6b06d830a180a448e51ec6483af05ece7a788883d68739732fc/plib3.io-0.10.post1.tar.gz" } ], "0.10.post2": [ { "comment_text": "", "digests": { "md5": "8a9210f2064b30115b2e33d12b9b0ec4", "sha256": "c628859a011bf3f0eb8f8509e7a9ec34a8ff90849a1dcea107977616b24e20e0" }, "downloads": -1, "filename": "plib3.io-0.10.post2.tar.gz", "has_sig": false, "md5_digest": "8a9210f2064b30115b2e33d12b9b0ec4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 111540, "upload_time": "2019-09-24T00:25:35", "url": "https://files.pythonhosted.org/packages/e4/4e/a153623f34fc3c6c48efd667ef9df3030aad6b0d4531482b327a782c8324/plib3.io-0.10.post2.tar.gz" } ], "0.9.3": [ { "comment_text": "", "digests": { "md5": "521e04d1eaa3a36b1be2b5699a546305", "sha256": "6d00fb76d6d9c7e3879b89094b881b1e1c98d40bc54131096485b170aa35981c" }, "downloads": -1, "filename": "plib3.io-0.9.3.tar.gz", "has_sig": false, "md5_digest": "521e04d1eaa3a36b1be2b5699a546305", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 98841, "upload_time": "2013-06-12T22:34:05", "url": "https://files.pythonhosted.org/packages/8f/ee/f10ddb0efed54f068dcb8168be16732ebf831fbf75fd1f448a888541d424/plib3.io-0.9.3.tar.gz" } ], "0.9.4": [ { "comment_text": "", "digests": { "md5": "af735fe442c13503c1dfc630b5449eb6", "sha256": "a234f83db3f531bdf37759f18b5ac4e1008661f0d92cb22bcda2252e31e4b7ec" }, "downloads": -1, "filename": "plib3.io-0.9.4.tar.gz", "has_sig": false, "md5_digest": "af735fe442c13503c1dfc630b5449eb6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 98937, "upload_time": "2013-06-14T14:48:59", "url": "https://files.pythonhosted.org/packages/76/ea/3c81bce026c2bf383b9cfb5d940f41fd71208f2a8c378c82bb45ca4ab07f/plib3.io-0.9.4.tar.gz" } ], "0.9.5": [ { "comment_text": "", "digests": { "md5": "c6bd3ef4fb6f8d878222c26a9228e2f9", "sha256": "89f420ac75584dc9e9df4bf2f30441358d0002ffec507ecf71fff422b6209204" }, "downloads": -1, "filename": "plib3.io-0.9.5.tar.gz", "has_sig": false, "md5_digest": "c6bd3ef4fb6f8d878222c26a9228e2f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 97415, "upload_time": "2013-06-20T23:48:35", "url": "https://files.pythonhosted.org/packages/c9/32/8347a28742fc21e0c3d908f8ad4fe5fee8d7ea1265c7eac793f0528a5cba/plib3.io-0.9.5.tar.gz" } ], "0.9.6": [ { "comment_text": "", "digests": { "md5": "6024d4fe5898865b497212ce0f3a48a0", "sha256": "754304598bd2cdd2894004b92f1bf23b499753d29eaad6d794a8890917839672" }, "downloads": -1, "filename": "plib3.io-0.9.6.tar.gz", "has_sig": false, "md5_digest": "6024d4fe5898865b497212ce0f3a48a0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 99357, "upload_time": "2013-07-01T22:40:36", "url": "https://files.pythonhosted.org/packages/0a/69/2d5b009472855dbec288c0095c94124db00830ba90f0b9bea38e9f3216f4/plib3.io-0.9.6.tar.gz" } ], "0.9.7": [ { "comment_text": "", "digests": { "md5": "8609524aafffacf47eb9b22b3463e25a", "sha256": "c5e2ddce0c14c9fdc471605f7cbfeb3bd42bf794cbb0b57bc2fb78deb23bc1b7" }, "downloads": -1, "filename": "plib3.io-0.9.7.tar.gz", "has_sig": false, "md5_digest": "8609524aafffacf47eb9b22b3463e25a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 111015, "upload_time": "2015-07-27T21:24:49", "url": "https://files.pythonhosted.org/packages/16/22/9d485cf62a08614c0c63d16ed2ecad24bf2188d7a0d9eda322099e0fec6d/plib3.io-0.9.7.tar.gz" } ], "0.9.8": [ { "comment_text": "", "digests": { "md5": "6c141bc8f9ddd028cffe26a3541baadb", "sha256": "cd979f94d55f3919b79200ac330ae5f17129d4565f387d6c775f5516cd47ad63" }, "downloads": -1, "filename": "plib3.io-0.9.8.tar.gz", "has_sig": false, "md5_digest": "6c141bc8f9ddd028cffe26a3541baadb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 111541, "upload_time": "2019-09-21T03:03:04", "url": "https://files.pythonhosted.org/packages/e7/44/60f80aae0807ab40b995468d6195a712053a6b80ad33f631e2a1e200f16b/plib3.io-0.9.8.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e571eb222aba57480d7500f679eb3c39", "sha256": "a594a47d774079d1509fd44ec7d5c4dd9bc8de36aad226b12cdbacfeed038bfc" }, "downloads": -1, "filename": "plib3.io-0.10.4.tar.gz", "has_sig": false, "md5_digest": "e571eb222aba57480d7500f679eb3c39", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 112057, "upload_time": "2019-09-29T02:53:10", "url": "https://files.pythonhosted.org/packages/b2/cd/fc37ee0bf273f969dbf5b401d54ffe4b9479720e51a8cac1936f71516439/plib3.io-0.10.4.tar.gz" } ] }