{ "info": { "author": "Outernet Inc", "author_email": "apps@outernet.is", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.4", "Topic :: Software Development :: Libraries :: Application Frameworks" ], "description": "====\nconz\n====\n\nThis module contains a lightweight library for creating command line programs,\nconz.\n\nconz has following features:\n\n- Simplifies working with pipes\n- Provides methods for handling typical interactive scenarios\n- Supports output colorization\n- Provides tools for working with long-running tasks\n- Controls output in interactive and non-interactive scenarios\n- Manages signals (SIGINT and SIGPIPE)\n\n.. contents::\n\nInstalling\n==========\n\nYou can install conz from PyPI using pip or easy_install::\n\n pip install conz\n\n easy_install conz\n\nQuick tour\n==========\n\nA quick tour example can be found in ``examples/quicktour.py``::\n\n import conz\n\n someval = True\n\n cn = conz.Console(verbose=True)\n\n cn.pstd('This goes to STDOUT')\n cn.perr('This goes to STDERR')\n cn.pverr(someval, 'This message is related to somevar')\n\n cn.pstd(cn.color.green('This message is green'))\n\n with cn.progress('Some long operation'):\n import time\n time.sleep(2)\n\n data = cn.read('Type something in:')\n cn.pstd('You typed in {}'.format(cn.color.yellow(data, style='italic')))\n\nFormatting conventions\n======================\n\nBecause this library deals with terminal output a lot, we have to somehow tell\nwhen something is terminal output and when it is code. Because of this, we use\nlines to delimit console output. For example::\n\n ----------------------------------------------\n I'm a sample output\n ----------------------------------------------\n\nWhen output is to the STDERR, 'E' will be shown in the right corner.::\n \n ---------------------------------------------E\n I'm a sample error\n ----------------------------------------------\n\nWhen user enters data, the Entered data will be followed by ```` and the\nright corner will include the 'I' character (for 'interactive session')::\n\n ---------------------------------------------I\n Prompt: some data\n ----------------------------------------------\n\nWhen value is returned from user input, the value is printed right below the\noutput preceeded by ``==>``::\n\n ---------------------------------------------I\n Prompt: some data\n ----------------------------------------------\n ==> 'some data'\n\nUsage\n=====\n\nThe ``conz`` package includes a class ``Console`` which is the only class you\nwill even need to work with. Simply import and instantiate it at the top of\nyour program. ::\n\n import conz\n cn = conz.Console()\n\nWorking with output\n-------------------\n\nThe ``Console()`` class is, for the most part, a wrapper around the ``print()``\nfunction (not print statement, so not compatible with versions of Python that\ndo not support this). It controls how ``print()`` is invoked and takes care of\nsome of the edge cases where it may malfunction.\n\nThe ``print()`` method on a ``Console`` object is a very simple wrapper around\nPython's ``print()`` whic does nothing except pass it's positional and keywrod\narguments to the ``print()`` function. We will never use it directly, though,\nas there are shortcuts for doing specific things with ``print()``.\n\nTo output to STDOUT, we use the ``pstd()`` method. It takes the same arguments\nas ``print()`` function, with the exception of ``file`` keyword argument which\nis set by this method and cannot be overridden. ::\n\n cn.pstd('This always goes to STDOUT', end='...')\n ----------------------------------------------\n This always goes to STDOUT\n ----------------------------------------------\n\nTo output to STDERR, we use the ``perr()`` method. As with ``pstd()``, it\noverrides the ``file`` argument for us. ::\n\n cn.perr('Mayday, mayday!')\n ---------------------------------------------E\n Mayday, mayday!\n ----------------------------------------------\n\nThe main difference between regular ``print()`` and ``pstd()``/``perr()``\nmethods is that the latter will flush the STDOUT/STDERR after writing to it.\nThis can prvent weird issues in some edge cases.\n\nThere is a variant of ``perr()`` which prints a more structured message to\nSTDERR. The ``pverr()`` method takes a value and a message, and prints then in\n``VALUE: Message`` format. ::\n\n path = '/foo/bar/baz.txt'\n cn.verr(path, 'not found')\n ---------------------------------------------E\n /foo/bar/baz.txt: not found\n ----------------------------------------------\n\nA variant of ``pstd()`` is ``pverb()``. It is exactly the same as ``pstd()``,\nexcept that it only outputs when ``verbose`` flag on the ``Console`` object is\n``True``. This is useful for programs that need to differentiate between\ninteractive and non-interactive use (e.g., using in pipe vs invoking directly)\nor wish to have a ``--verbose`` switch, etc. ::\n\n cn.verbose = True\n cn.pverb(\"I'm a talkative program\")\n ----------------------------------------------\n I'm a talkative program\n ----------------------------------------------\n\n cn.verbose = False\n cn.pverb(\"I'm a talkative program\")\n ----------------------------------------------\n\n ----------------------------------------------\n\nThe ``verbose`` flag can be set either as an argument during instantiation, or\nsimply by setting the attribute as in the previous example.\n\nThe ``Console`` object also provides a ``outterm`` property which is ``False``\nwhen program is outputting to a pipe rather than the terminal::\n\n if cn.outterm:\n # give full output to the user\n else:\n # give a short output that can be parsed by a machine, etc\n\nColorizing\n----------\n\nBefore we start, note that this implementation is **not cross-platform**. If\nyou need something with a bit more punch, you should look at colorama_.\n\nTo colorize the output, both the ``conz`` module and ``Console`` class have a \n``color`` attribute, which provides methods for output colorization. Each piece\nof text can have the following attributes:\n\n- foreground color\n- style\n- background color\n\nForeground and background colors can be:\n\n- black\n- red\n- green\n- yellow\n- blue\n- purple (magenta)\n- cyan\n- white\n\nStyles can be:\n\n- bold\n- italic\n- underline\n- blink\n- reverse (inverts foreground and background colors)\n\nEach of these colors have a method on the ``color`` attribute. Each color\nmethod takes ``style`` and ``bg`` keyword arguments which set the style and\nbackground color respectively. The ``color()`` method can be used to specify\ncolors dynamically. Here are some examples::\n\n cn.color.red('This is red text')\n cn.color.color('This is red text', color='red')\n cn.color.blue('This is blue underlined text', style='underline')\n cn.color.color('This is green on yellow', color='green', bg='yellow')\n\nYou can find an example script in ``examples/colors.py`` which prings all\npossible combinations of various colors, styles, and backgrounds.\n\nWorking with input\n------------------\n\nThere are two types of input you can work with: interactive user input, and \npipes.\n\nTo read the user input, use ``read()`` method. This method takes two optional \narguments. One is the ``prompt`` argument, which we use to set the prompt. It\nis an empty string by default. The other argument is a data-cleaning function.\nWhen you pass the ``clean`` argument, user input is passed through the function\nbefore it is retuned. For example::\n\n cn.read('Exit? [y/N] ', clean=lambda x: x.lower()[:1] == 'y')\n ---------------------------------------------I\n Exit? [y/N] y\n ----------------------------------------------\n ==> True\n\nNote that this method uses ``raw_input()`` on Python 2.7.x and ``input()`` on\nPython 3.x.\n\nTo work with pipes, we use the ``readpipe()`` method. This method reads from\nthe STDIN pipe one line at a time and returns an iterator that allows us to\niterate over the lines. ::\n\n for l in cn.readpipe():\n l = l.strip()\n cn.pstd('Received: {}'.format())\n\nNote that line-feed characters are not stripped from the output so it is up to\nus to strip it away.\n\nWhen working with a large number of lines coming down the pipe, we may\nsometimes need to work in batches, rather than one line at a time. The\n``chunk`` argument can be set to an integer value that specifies the number of\nlines we want buffered before they are returned to us. When using chunks, the\nlines are returned as a list of strings, rather than strings. The following\nexample will return pipe input in groups of 500::\n\n for lines in cn.readpipe(500):\n # do something with 500 lines\n\nIf we need to know whether input will come from a pipe or not, we can use the\n``interm`` property. ::\n\n if cn.interm:\n # possibly interactive version\n else:\n # we are on the receiving end of a pipe\n\nAdvanced interactive input\n--------------------------\n\nSo far we have looked at simpe user input. However in most cases, input is not\nthe only thing we want. We normally also need to show notes, validate the\ninput, construct menus, etc. The ``Console`` class provides three methods that\nare useful for different scenarios.\n\nYou will find examples of code discussed here in ``examples/user_input.py`` and\n``examples/menu.py``.\n\nRVPL\n~~~~\n\nRVPL (pead validate print loop) is a loop in which some data is read from the\nuser, validated, and error message printed. This loop continues as long as data\nis invalid. The ``rvpl()`` method is used to start such a loop.\n\nAt bare minimum, ``rvpl()`` is called with a prompt that should be shown to the\nuser. ::\n\n cn.rvpl('Please enter your name:')\n ---------------------------------------------I\n Please enter your name: My name\n ----------------------------------------------\n ==> 'My name'\n\nLike ``read()``, ``rvpl()`` also takes a ``clean`` argument, which is used to\ncontrol how the value is cleaned. In addition, it takes ``validator`` argument,\nwhich is a function that validates the cleaned data. The default validator\nsimply makes sure the input is not an empty string.\n\nFor invalid input, error message is displayed::\n\n cn.rvpl('Please enter your name:')\n ---------------------------------------------I\n Please enter your name: \n Entered value is invalid\n Please enter your name: Mike\n ----------------------------------------------\n ==> 'Mike'\n\nError message can be customized using the ``error`` argument. If ``error``\nargument is is a callable, it will be called with entered value and it must \nreturn the message to be shown. ::\n\n valid_input = ('a', 'b', 'c')\n error = lambda x: '{} is not one of the {}'.format(\n x, ', '.join(valid_input))\n validator = lambda x: x in valid_input\n cn.rvpl('Type one of the first 3 characters of English alphabet:')\n ---------------------------------------------I\n Type one of the first 3 characters of English alphabet: e\n e is not one of the a, b, c\n Type one of the first 3 characters of English alphabet: b\n ----------------------------------------------\n ==> 'b'\n\nAn intro message can be passed which is shown above the prompt. Unlinke the\nprompt itself, intro message is not repeated in the loop. ::\n\n cn.rvpl('>', intro='Please enter your name:')\n ---------------------------------------------I\n Please enter your name: \n > \n Entered value is invalid\n > Mike\n ----------------------------------------------\n ==> 'Mike'\n\nWhen requesting optional input, the strict validation can be turned off using\nthe ``strict`` argument. When this argument is ``False``, then the loop exists\neven when validation fails. The value returned when validation fails is\ncontrolled by ``default`` argument, which defaults to ``None``. ::\n\n cn.rvpl('Please enter your name:', strict=False, default='Bob')\n ---------------------------------------------I\n Please enter your name: \n ----------------------------------------------\n ==> 'Bob'\n\nYes/No input\n~~~~~~~~~~~~\n\nThe ``yesno()`` method provides a specialized version the RVPL limited to yes\nand no answer, and returnin ``True`` or ``False``. ::\n\n cn.yesno('Are you all right?')\n ---------------------------------------------I\n Are you all right? (y/n): y\n ----------------------------------------------\n ==> True\n\nThe prompt passed to ``yesno()`` is automatically appended the '(y/n):' string.\nThe appearance of this string depends on the default value discussed further\nbelow.\n\nSince it is a wrapper around ``rvpl()`` it takes the same ``error`` and\n``intro`` arguments which behave the same way.\n\nAlthough it takes the ``default`` argument like ``rvpl()``, the behavior is\ndifferent. When ``default`` is ``None`` it automatically turns on strict\nvalidation. The argument can also be either ``True`` or ``False``, in which\ncase the default value is respectively 'yes' and 'no'. ::\n\n cn.yesno('Are you all right?', default=True)\n ---------------------------------------------I\n Are you all right? (Y/n): \n ----------------------------------------------\n ==> True\n \n cn.yesno('Are you all right?', default=False\n ---------------------------------------------I\n Are you all right? (y/N): \n ----------------------------------------------\n ==> False\n\nMenu\n~~~~\n\nMenu is another specialization of the RVPL, used for displaying menus. This is\nfacilitated by the ``menu()`` method. \n\nThis method has only one required argument, which is an iterable of menu\nchoices. Each member of the iterable must be a two-tuple which holds the actual\nvalue as first member and the value's label as second. For example::\n\n choices = (('f', 'foo'), ('b', 'bar'))\n cn.menu(choices)\n ---------------------------------------------I\n 1) foo\n 2) bar\n Please choose from the provided options: 1\n ----------------------------------------------\n ==> 'f'\n\nAlmost all aspects of the menu can be customized. The ``prompt``, ``error``,\n``intro``, ``strict`` and ``default`` behave the same way as in regular RVPL so\nwe will not discuss them in detail here.\n\nDisplay of the menu items themselves is controlled by two arguments:\n``formatter`` and ``numerator``.\n\n``numerator`` argument controls how the enumeration of the menu items is done.\nIt takes the number of menu items as its only argument, and must return a list\nof strings to be used as options. For example::\n\n choices = (('f', 'foo'), ('b', 'bar'))\n numer = lambda n: ('abcd'[i] for i in range(n), numerator=numer)\n cn.menu(choices)\n ---------------------------------------------I\n a) foo\n b) bar\n Please choose from the provided options: a\n ----------------------------------------------\n ==> 'f'\n\n``formatter`` takes the number of the item and item's label and must return a\nformatted menu item. For example::\n\n choices = (('f', 'foo'), ('b', 'bar'))\n fmt = lambda n, lbl: '{} ({})'.format(lbl, n)\n cn.menu(choices, formatter=fmt)\n ---------------------------------------------I\n foo (1)\n bar (2)\n Please choose from the provided options: 1\n ----------------------------------------------\n ==> 'f'\n\nWorking with progress\n---------------------\n\nProgress is a more complex construct that we use to notify user of some\nactivity that may take a while. Each progress has a start banner, which is\nprinted before we begin, and two end banners, one for success and one for\nfailure.\n\nBefore we can use the progress context manager, we must enable verbose mode. ::\n\n cn.verbose = True\n\nA progress is started using the ``progress()`` method, which is a context\nmanager. ::\n\n with cn.progress(\"Let's get this show on the road\"):\n # do something\n\nThis is the simplest form. When an exception of any kind is triggered inside\nthe context, it is trapped, the failure banner is printed, and the\n``conz.ProgressAbrt`` exception is raised. (This exception is also available as\nan attribute on ``Console`` objects for convenience.) If everything goes well,\nthen the success banner will be printed. With the previous code snippet, sucess\noutput may look like this::\n\n ----------------------------------------------\n Let's get this show on the road...DONE\n ----------------------------------------------\n\nAnd failure would look like this::\n\n ----------------------------------------------\n Let's get this show on the road...FAIL\n ----------------------------------------------\n\nThe end banners can be customized by using the ``end`` and ``abrt`` arguments::\n\n with cn.progress('Almost there', end='finally!', abrt='awww, bummer'):\n # do something\n\nThe outputs would look like this::\n\n ----------------------------------------------\n Almost there...finally!\n ----------------------------------------------\n\nor::\n\n ----------------------------------------------\n Almost there...awww, bummer\n ----------------------------------------------\n\nThe elipsis (three dots) can be customized using the ``sep`` argument::\n\n with cn.progress('File check', sep=': '):\n # do something\n\nThis results in::\n\n ----------------------------------------------\n File check: DONE\n ----------------------------------------------\n\nor::\n\n ----------------------------------------------\n File check: FAIL\n ----------------------------------------------\n\nBy default, the progress context manager will trap any exception. This may or\nmay not make sense for a particular situation. This behavior can therefore be\ncustomized using the ``excs`` argument, which takes a tuple of exception\nclasses that we are expecting. Passing exceptions explicitly like this allows\nthe context manager to propagate unhandled exceptions and reval subtle flaws in\nour logic.\n\nWe can also specify a callback that runs each time an exception (other than\n``ProgressAbrt`` and ``ProgressOK`` are raised inside the context. This\ncallback is specified using ``onerror`` argument, and defaults to an error\nhandler that prints 'Program error: ERROR MESSAGE' to STDERR. For convenience,\nthe ``Console`` object has a ``error()`` method which creates such handlers.\n\nBy default, the tracebacks raised during progress is suppressed. To see the\nfull traceback, ``Console`` constructor takes a ``debug`` argument, which can\nbe set to ``True`` to prevent traceback suppression.\n\nTo create a handler, we call the ``error()`` method like so::\n\n handler = cn.error('Ouch!', exit=1)\n with cn.progress('Ouch progress', onerror=handler):\n raise RuntimeError()\n\nThe above results in::\n\n ----------------------------------------------\n Outch progress...FAIL\n Ouch!\n ----------------------------------------------\n\nThe message may have a ``{err}`` placeholder, which gets replaced by the string\nrepresentation of the exception that was raised in the block.\n\nTo completely suppress the error handler, simply pass it a function that does\nnothing. ::\n\n with cn.progress('No ouch', onerror: lambda exc: None):\n raise RuntimeError()\n ----------------------------------------------\n No ouch...FAIL\n ----------------------------------------------\n\n.. note::\n Note that passing ``None`` as ``onerror`` value simply causes the default\n error handler to be used instead.\n\nThe progress context manager returns a ``Progress`` object, which provides\nmethods for explicitly terminating the progress, and printing the progress\nindicator. This object has ``end()`` and ``abrt()`` methods, which are called\nto terminate with success and error status respectively. For example::\n\n with cn.progress('Something') as prg:\n if not success:\n prg.abrt()\n prg.end()\n\nThe ``end()`` and ``abrt()`` methods raise ``ProgressOK`` and ``ProgressAbrt``\nexceptions repsectively. We can suppress raising of the exceptions using\n``noraise`` argument and setting it to ``True``. Both of the methods will use\nthe default end banners. We can also use any banner we want by passing it as\nthe first positional argument. This can be useful in cases where the end banner\nshould indicate different outcomes.\n\n.. note::\n Default banners are colorized (green for success, red for failure). Any\n custom banners passed directly to ``end()`` and ``abrt()`` will not be\n colorized, though.\n\nThe ``ProgressOK`` exception is not meant to be\nhandled by us in any way, and it's simply there to facilitate flow control.\n``ProgressAbrt`` is, by default, reraised so that code outside the context\nmanager can handle it. Therefore, we normally wrap the context block in a\ntry-except::\n\n try:\n with cn.progress('Something'):\n # do something\n except cn.ProgressAbrt:\n # something went wrong\n\nThis reraising of the ``ProgressAbrt`` exception can be suppressed by using the\n``reraise`` argument which can be ``True`` or ``False``. Setting this flag to\n``False`` silences the ``ProgressAbrt`` exception. At that point, we are still\nable to do error handling using the ``onerror`` callback.\n\nYou can find a script in ``examples/progress.py`` which demonstrates a few\ntypical cases.\n\nQuitting\n--------\n\nTo quit the program, we call the ``quit()`` method on the ``Console`` object.\nThis method works the same way as ``sys.exit()`` (except that it takes one less\n``import`` to use it).\n\nSignal handling\n---------------\n\nThe default implementation of ``Console`` class automatically takes care of\n``SIGINT`` (keyboard interrupt) and ``SIGPIPE`` (broken pipe) signals. You can\ncustomize the way those are handled by overloading the ``onint()`` and\n``onpipe()`` methods. You can also customize the registration of signals\nthemselves by overloading the ``register_signals()`` method.\n\n\nReporting bugs\n==============\n\nPlease report any bugs or feature requests to the `issue tracker`_.\n\n.. _colorama: https://pypi.python.org/pypi/colorama\n.. _issue tracker: https://github.com/Outernet-Project/conz/issues", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Outernet-Project/conz", "keywords": "console,terminal,signals,output,command line,colorizing", "license": "GPLv3", "maintainer": null, "maintainer_email": null, "name": "conz", "package_url": "https://pypi.org/project/conz/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/conz/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/Outernet-Project/conz" }, "release_url": "https://pypi.org/project/conz/0.5/", "requires_dist": null, "requires_python": null, "summary": "Library for writing command line programs", "version": "0.5" }, "last_serial": 1543562, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "f52c11e4c2848397c160631b12d367bd", "sha256": "802083734f8ab220966dcdb67d717440510e17fc9c978667853868a206a9b4e7" }, "downloads": -1, "filename": "conz-0.1.tar.gz", "has_sig": false, "md5_digest": "f52c11e4c2848397c160631b12d367bd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22941, "upload_time": "2015-05-05T11:38:08", "url": "https://files.pythonhosted.org/packages/6e/13/6a057f5dfe72f7cf2a0c5a0ce45d6f2f908a6fcc5080f71d31dcfa3aee05/conz-0.1.tar.gz" }, { "comment_text": "", "digests": { "md5": "9f033520e8e2e7eab1073a4800504a5e", "sha256": "f3d3e817093b1e851e3530713a3c14051a33065a7db331374558425d29dccd08" }, "downloads": -1, "filename": "conz-0.1.zip", "has_sig": false, "md5_digest": "9f033520e8e2e7eab1073a4800504a5e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29641, "upload_time": "2015-05-05T11:38:12", "url": "https://files.pythonhosted.org/packages/71/0b/21bdd7bd469effb4ec01091f0d15fedce2fb31c257e76528ba20bd1c3d89/conz-0.1.zip" } ], "0.1.post1": [ { "comment_text": "", "digests": { "md5": "a8b48df06722a036447c75a28cbcd212", "sha256": "7a4d384fe63b87167538832bec1044882148888a78693bc8c23852919ac10dfb" }, "downloads": -1, "filename": "conz-0.1.post1.tar.gz", "has_sig": false, "md5_digest": "a8b48df06722a036447c75a28cbcd212", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26142, "upload_time": "2015-05-05T11:51:10", "url": "https://files.pythonhosted.org/packages/ea/c0/1c908dba92f1bb833cf9287ef9d90971a7efb298fbd094cdd5b299ee0830/conz-0.1.post1.tar.gz" }, { "comment_text": "", "digests": { "md5": "991fe84e0fd1051a82d8e188a7f36d0b", "sha256": "26080893c1b92df6310b31c23676c137ef26a0365565cc64219a56b6a972c8f8" }, "downloads": -1, "filename": "conz-0.1.post1.zip", "has_sig": false, "md5_digest": "991fe84e0fd1051a82d8e188a7f36d0b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33571, "upload_time": "2015-05-05T11:51:13", "url": "https://files.pythonhosted.org/packages/44/a8/68293e003fea667086f941f6242f4161f551bcf29334745d562c26178c2b/conz-0.1.post1.zip" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "f00e6da213a0044a0a7d9f3ad45390cf", "sha256": "61e1fb0f191d008ce11a24e824e051f5975018096159f57a245dfc4210758e10" }, "downloads": -1, "filename": "conz-0.2.tar.gz", "has_sig": false, "md5_digest": "f00e6da213a0044a0a7d9f3ad45390cf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26151, "upload_time": "2015-05-05T12:23:46", "url": "https://files.pythonhosted.org/packages/70/a1/9dc537a1f87444042cf26e4fd9ef3bfeb1eb7102f48d0a33d2cccf5a67e0/conz-0.2.tar.gz" }, { "comment_text": "", "digests": { "md5": "027911ed85096bdd9aa840a50354bcca", "sha256": "da37aee6c6ab69584a2398ddbd3bb8b80d3fe4eae6f25ebb95ca79f0344484bd" }, "downloads": -1, "filename": "conz-0.2.zip", "has_sig": false, "md5_digest": "027911ed85096bdd9aa840a50354bcca", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33449, "upload_time": "2015-05-05T12:23:50", "url": "https://files.pythonhosted.org/packages/47/6a/12891f863214ebe0ec8a8fd70b7f2e5d194e69a2fcd26de639f55dee251b/conz-0.2.zip" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "94c67980ddde115b20b967d2d0230a7e", "sha256": "313d8951872a48983c06762c1498719d09f32dbbef7704490091396f1f3a968a" }, "downloads": -1, "filename": "conz-0.3.tar.gz", "has_sig": false, "md5_digest": "94c67980ddde115b20b967d2d0230a7e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32395, "upload_time": "2015-05-06T09:51:28", "url": "https://files.pythonhosted.org/packages/75/aa/588d7949a30e83fec8a63e9c3090501eba475123b9bedde40288d1ab7958/conz-0.3.tar.gz" }, { "comment_text": "", "digests": { "md5": "4288080d9067a78a9dd773b21e9467da", "sha256": "2c12d2074403a10cba68b5c5bc6b497b6f31db84758a4c4dcdfcb498bbc721a8" }, "downloads": -1, "filename": "conz-0.3.zip", "has_sig": false, "md5_digest": "4288080d9067a78a9dd773b21e9467da", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43080, "upload_time": "2015-05-06T09:51:31", "url": "https://files.pythonhosted.org/packages/db/9a/355ab8ab2d41e7324a6ea9d8270cc2cd4a156a4972af437fa35cf4b580b4/conz-0.3.zip" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "b99855de3cc6d38e62b6f0e57c59265a", "sha256": "bfcb73e96df7e4e0d03842f7b3b0c13b4d1324870e235abd7c9812588033333b" }, "downloads": -1, "filename": "conz-0.4.tar.gz", "has_sig": false, "md5_digest": "b99855de3cc6d38e62b6f0e57c59265a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32614, "upload_time": "2015-05-07T13:33:12", "url": "https://files.pythonhosted.org/packages/4d/4a/43794e666b601c83e24236255d004b84609bfcfd39a1fa3ee5ae3f3870cc/conz-0.4.tar.gz" }, { "comment_text": "", "digests": { "md5": "873311d1e2b4320621523d69cb0e55aa", "sha256": "8cfa1a38930e7bd91400d7ab29555367de1cdd97e199d5d0a83e90d64ee42db7" }, "downloads": -1, "filename": "conz-0.4.zip", "has_sig": false, "md5_digest": "873311d1e2b4320621523d69cb0e55aa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43376, "upload_time": "2015-05-07T13:33:16", "url": "https://files.pythonhosted.org/packages/95/a5/ccf3b500cd1d50973596ce4e2dbcda919f822302fc28c761349e0e064482/conz-0.4.zip" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "61ca0c489348f33cf71158f97e241d85", "sha256": "ede5f89bfec00f43aff04ef97a8308fd0df99a0f7d848a0e8526b7162a2763c3" }, "downloads": -1, "filename": "conz-0.5.tar.gz", "has_sig": false, "md5_digest": "61ca0c489348f33cf71158f97e241d85", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32724, "upload_time": "2015-05-12T11:56:29", "url": "https://files.pythonhosted.org/packages/61/9b/9bba56fc649c7828b0693a9f0d58f984e48164e945cb17318603d5243070/conz-0.5.tar.gz" }, { "comment_text": "", "digests": { "md5": "f168058eac3ebb71f2baa9bc62af0dc2", "sha256": "e9520ee8a3caa0bf92532a52f4a07b454c2a48e4bbd40f5d66f5e9cf8dea723e" }, "downloads": -1, "filename": "conz-0.5.zip", "has_sig": false, "md5_digest": "f168058eac3ebb71f2baa9bc62af0dc2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43488, "upload_time": "2015-05-12T11:56:33", "url": "https://files.pythonhosted.org/packages/dc/c4/5ac466369c40d12cec693e56626dd9adfc50d47c44634c1335bb424f0382/conz-0.5.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "61ca0c489348f33cf71158f97e241d85", "sha256": "ede5f89bfec00f43aff04ef97a8308fd0df99a0f7d848a0e8526b7162a2763c3" }, "downloads": -1, "filename": "conz-0.5.tar.gz", "has_sig": false, "md5_digest": "61ca0c489348f33cf71158f97e241d85", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32724, "upload_time": "2015-05-12T11:56:29", "url": "https://files.pythonhosted.org/packages/61/9b/9bba56fc649c7828b0693a9f0d58f984e48164e945cb17318603d5243070/conz-0.5.tar.gz" }, { "comment_text": "", "digests": { "md5": "f168058eac3ebb71f2baa9bc62af0dc2", "sha256": "e9520ee8a3caa0bf92532a52f4a07b454c2a48e4bbd40f5d66f5e9cf8dea723e" }, "downloads": -1, "filename": "conz-0.5.zip", "has_sig": false, "md5_digest": "f168058eac3ebb71f2baa9bc62af0dc2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43488, "upload_time": "2015-05-12T11:56:33", "url": "https://files.pythonhosted.org/packages/dc/c4/5ac466369c40d12cec693e56626dd9adfc50d47c44634c1335bb424f0382/conz-0.5.zip" } ] }