{ "info": { "author": "nehem", "author_email": "nehemiah.jacob@gmail.com", "bugtrack_url": null, "classifiers": [], "description": ".. figure:: https://raw.githubusercontent.com/nehemiahjacob/tissuebox/master/tissuebox.png\n\nTissuebox\n---------\n\nTissuebox is a pure Pythonic schema validator which takes advantage of\nPython\u2019s functional style programming to provide simple yet powerful\nvalidation framework. The standard usage would be validating incoming\nJSON objects upon http requests or to validate any Python dict in other\ncommon scenarios.\n\nInstallation:\n^^^^^^^^^^^^^\n\nUse ``pip`` to install Tissuebox\n\n``pip install tissuebox``\n\nRequirements:\n^^^^^^^^^^^^^\n\nTissuebox requires Python 3.7 however we are considering to add support\nfor earlier versions of Python3\n\nExamples:\n^^^^^^^^^\n\nAssume the incoming JSON object or a python dict which contains hotel\ndetails and we will build upon this example.\n\n.. code:: python\n\n payload = {\n \"name\": \"Park Shereton\",\n \"available\": True,\n \"price_per_night\": 270,\n \"email\": \"contact@shereton.com\",\n \"web\": \"www.shereton.com\",\n }\n\n1. Validating basic data types\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou can use ``tissuebox`` to define a schema to validate the payload\nagainst basic data types and validate using ``validate`` method.\n\n.. code:: python\n\n from tissuebox import validate\n from tissuebox.basic import boolean, integer, string\n\n schema = {\n 'name': string,\n 'available': boolean,\n 'price_per_night': integer\n }\n\n validate(schema, payload)\n\nwill return\n\n.. code:: python\n\n (True, [])\n\n2. Validating common datatypes\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nA ``tissuebox`` schema is simply a dict where keys are payload keys and\nvalues are type_functions to which the payload value would be passed. A\ntype_function simply accepts a single parameter and returns a tuple with\ntwo items ``(boolean, msg)``.\n\nTissuebox aims to amass a collection of commonly used types to it\u2019s\nlibrary. For now common data types like ``email``, ``url``,\n``rfc_datetime``, ``geolocation`` are part of ``tissuebox``\\ \u2019s standard\ncollections. You can contribute more via Github.\n\n.. code:: python\n\n from tissuebox import validate\n from tissuebox.basic import email, integer, string, url\n schema = {\n 'name': string,\n 'price_per_night': integer,\n \"email\": email,\n \"web\": url\n }\n\n validate(schema, payload)\n\nwill return\n\n.. code:: python\n\n (True, [])\n\nOne of the ways ``tissuebox`` stands our from other alternatives is, the\ntype_functions are stored and passed around as Python variables which is\nhelpful in identifying the schema definition errors ahead of time as\nmost IDEs will display squiggly lines if the variables aren\u2019t resolved,\nwhile other frameworks like JsonSchema and Cerebrus pass types within\nstrings which is hard for IDEs to detect errors in the schema.\n\n3. Validating nested fields\n^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nMethod 1:\n'''''''''\n\nDefining a schema in a nested fashion is very straight forward which\nenables re-use schemas around. Consider if the payload has an\n``address`` field. We can define a separate schema as ``address_schema``\nand pass it to the main schema as below.\n\n.. code:: python\n\n from tissuebox import validate\n from tissuebox.basic import email, integer, string, url\n payload = {\n \"name\": \"Park Shereton\",\n \"available\": True,\n \"price_per_night\": 270,\n \"email\": \"contact@shereton.com\",\n \"web\": \"www.shereton.com\",\n \"address\": {\n \"street\": \"128 George St\",\n \"city\": \"Sydney\",\n \"state\": \"NSW\",\n \"zip\": 2000\n }\n }\n\n address = {\n \"street\": string,\n \"city\": string,\n \"state\": string,\n \"zip\": integer\n }\n\n schema = {\n 'name': string,\n 'price_per_night': integer,\n \"email\": email,\n \"web\": url,\n \"address\": address\n }\n\n validate(schema, payload)\n\nwould return\n\n.. code:: python\n\n (True, [])\n\nMethod 2:\n'''''''''\n\nThe prefered method of defining nested schema is by using ``.`` dot as\ndelimiter to represent nested fields of the payload hierarchy.\nApparently this comes up with the downside wherein if ``.`` dot itself\nis part of keys which would be an unfortunate scenario. But it can\nimprove the readability to a tremendous level. See it yourself how\nelegantly we can express the schema once we introduce the ``address``\nfield to our payload.\n\n.. code:: python\n\n schema = {\n 'name': string,\n 'price_per_night': integer,\n \"email\": email,\n \"web\": url,\n \"address.street\": string,\n \"address.city\": string,\n \"address.state\": string,\n \"address.zip\": integer\n }\n\nThe primary reason why we suggest the later method is we can quickly\ndefine a nested field with any depth without creating unnecessary schema\nobjects in the middle.\n\n4. Validating enums.\n^^^^^^^^^^^^^^^^^^^^\n\nLet us try enforcing that the field ``address.state`` must be one of 8\nAustralian states. Tissuebox let\u2019s you define an enum using the ``{}``\ni.e ``set()`` syntax. Look at the example below.\n\n.. code:: python\n\n schema = {\n 'name': string,\n 'price_per_night': integer,\n \"email\": email,\n \"web\": url,\n \"address.state\": {'ACT', 'NSW', 'NT', 'QLD', 'SA', 'TAS', 'VIC', 'WA'},\n \"address.zip\": integer\n }\n\nTo have a feel how Tissuebox responds when we pass something which is\nnot an Australian state\n\n.. code:: python\n\n payload = {\n \"name\": \"Park Shereton\",\n \"available\": True,\n \"price_per_night\": 270,\n \"email\": \"contact@shereton.com\",\n \"web\": \"www.shereton.com\",\n \"address\": {\n \"street\": \"128 George St\",\n \"city\": \"Sydney\",\n \"state\": \"TX\",\n \"zip\": 2000\n }\n }\n\n validate(schema, hotel)\n\nwould return\n\n.. code:: python\n\n (False, ['[\"address\"][\"state\"] is failing to be enum of `{\\'SA\\', \\'QLD\\', \\'NT\\', \\'TAS\\', \\'VIC\\', \\'WA\\', \\'ACT\\', \\'NSW\\'}`'])\n\n5. Validating arrays\n^^^^^^^^^^^^^^^^^^^^\n\nLet us assume the payload has ``staffs`` which is array of staff names.\n\n.. code:: python\n\n payload = {\n \"name\": \"Park Shereton\",\n \"email\": \"contact@shereton.com\",\n \"web\": \"www.shereton.com\",\n \"staffs\" [\"John Doe\", \"Jane Smith\"],\n }\n\nNow the schema simple looks as below\n\n.. code:: python\n\n schema = {\n 'name': string,\n \"email\": email,\n \"web\": url,\n \"staffs\": [string]\n }\n\nSo in order to declare an element as array simply use ``[]`` syntax, if\nit\u2019s array of string simply say ``[string]``. If it\u2019s array of cats\nsimply say ``[cat]``. Array syntax can be either empty or single length\nwhere the element means a type_function or another nested schema.\n\nThere are two scenarios where Tissuebox implicitly handles the array.\n\n1. The incoming payload is simply list of dicts then Tissuebox knows\n that the given schema must be validated against all the items in the\n array.\n2. While declaring ``.`` dot separated nested attribute, and any of the\n middle element is array, Tissuebox is aware of such fact and will\n iterate the validation automatically.\n\nThese two cases are implemented to make Tissuebox as intuitive as\npossible,\n\n6. Writing custom validators\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nBy now you would have observed that ``tissuebox`` schema is simply a\ncollection of ``key:value`` pairs where ``value`` contains the data type\nverified against. ``tissuebox`` defines them in the style of\n``type_function`` which is simply a boolean function that takes one or\nmore parameters.\n\nLet us assume you want to validate the zip code as a valid Australian\none. Since ``tissuebox`` does\u2019t have a built-in type function, for that\npurpose you can come up with your own type function as below. For\nbrevity I\u2019ve removed few fields in the payload & schema.\n\n.. code:: python\n\n >>> def australian_zip(x):\n ... # https://www.etl-tools.com/regular-expressions/is-australian-post-code.html\n ... x = str(x)\n ... import re\n ... return re.match(r'^(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})$', x), \"must be a valida Australian zip\"\n ...\n >>> hotel = {\n ... \"address\": {\n ... \"zip\": 200\n ... }\n ... }\n >>>\n >>> schema = {\n ... \"address.zip\": australian_zip\n ... }\n >>>\n >>> validate(schema, hotel)\n (False, ['[\"address\"][\"zip\"] must be a valida Australian zip\"])\n\n7. Validating with type_functions that accept parameters.\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIn ``tissuebox`` type_functions always accept one argument which is the\npayload value. There are times for a type_function it makes sense to\naccepts multiple parameters. To achieve that they are declared as\nPython\u2019s higher order functions.\n\nLet us try validating where the ``price_per_night`` must be multiple of\n50. Also let us declare the Yelp review rating of a hotel must be\nbetween 1-5.\n\n.. code:: python\n\n >>> from tissuebox import validate\n >>> from tissuebox.basic import between, divisible, string\n\n >>> schema = {\n ... \"name\": string,\n ... \"rating\": between(1, 5),\n ... \"price_per_night\": divisible(50)\n ... }\n >>>\n >>> hotel = {\n ... \"name\": \"Park Shereton\",\n ... \"price_per_night\": 370,\n ... \"rating\": 5.1\n ... }\n >>>\n >>> validate(schema, hotel)\n (False, [\n '[\"price_per_night\"] is failing to be `divisible(50)`', \n '[\"rating\"] is failing to be `between(1, 5)`'\n ])\n\nFor curiosity here is the implementation of ``divisible`` from Tissuebox\nlibrary. It has been defined as a higher order function which returns\nanother function which always accepts single parameter. While writing\ncustom validators you are encouraged to use the same pattern.\n\n.. code:: python\n\n def divisible(n):\n def divisible(x):\n return numeric(x) and numeric(n) and x % n == 0, \"multiple of {}\".format(n)\n\n return divisible\n\n8. Combining multiple type_functions for same element\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAs we have observed ``tissuebox`` schema is a dict with ``key:value``\nformat. In Python keys in dicts are unique. It\u2019s a terrible idea to\nredeclare same key since the data will be overridden.\n\nAssume that you are attempting to do something like this\n\n.. code:: python\n\n from tissuebox.basic import divisible, integer, positive, string\n schema = {\n 'name': string,\n 'price_per_night': integer,\n 'price_per_night': positive,\n 'price_per_night': divisible(50),\n \"address.zip\": integer\n }\n\nHere ``price_per_night`` will be overridden by the latest declaration\nwhich must be avoided. This can be solved with another special syntax\nwhich yet Pythonic\n\nSimply use ``()`` to chain type_functions.\n\n::\n\n ```python\n from tissuebox.basic import divisible, integer, positive, string\n\n schema = {\n 'name': string,\n 'price_per_night': (integer, positive, divisible(50)),\n \"address.zip\": integer\n }\n ```\n\nNow Tissuebox will iterate all these conditions against\n``price_per_night``\n\n9. Declaring a field as ``required``\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWhile Tissuebox validates the values with type_functions, it only does\nso only for the values are found in the payload. Otherwise they were\nsimply ignored silently.\n\nIn a situation where a specific value is expected in payload declared\nthem as ``required`` function. And it\u2019s a common scenario to combine\nthem under ``()`` operator as described in the above.\n\n.. code:: python\n\n from tissuebox.basic import integer, required, string\n schema = {\n 'name': (required, string),\n \"address.city\": (required, string),\n \"address.zip\": integer\n }\n\nTissuebox Advantages:\n^^^^^^^^^^^^^^^^^^^^^\n\n- Tissuebox has lots of advantages than the current alternatives like\n jsonschema, cerebrus etc.\n- Truly Pythonic and heavily relies on short & static methods. The\n schema definition itself takes full advantages of Python\u2019s built-in\n syntax like ``{}`` for enum, ``()`` for parameterized function,\n ``[]`` chaining multiple rules etc\n- Highly readable with concise schema definition.\n- Highly extensible with ability to insert your own custom methods\n without complicated class inheritance.\n- Ability to provide all the error messages upfront upon validation.\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/nehemiahjacob/tissuebox.git", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "tissuebox", "package_url": "https://pypi.org/project/tissuebox/", "platform": "", "project_url": "https://pypi.org/project/tissuebox/", "project_urls": { "Homepage": "https://github.com/nehemiahjacob/tissuebox.git" }, "release_url": "https://pypi.org/project/tissuebox/2019.01.22/", "requires_dist": null, "requires_python": "", "summary": "Tissuebox :: Pythonic payload validator", "version": "2019.01.22" }, "last_serial": 4723902, "releases": { "18.12.1": [ { "comment_text": "", "digests": { "md5": "31813360055b15e71a20b5d1ebe7b9d8", "sha256": "924b97dafded9a593b7f862c7c937be726b489431d8371425019b47d70247e49" }, "downloads": -1, "filename": "tissuebox-18.12.1.tar.gz", "has_sig": false, "md5_digest": "31813360055b15e71a20b5d1ebe7b9d8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1650, "upload_time": "2018-12-05T11:22:22", "url": "https://files.pythonhosted.org/packages/85/d4/71f6b6d42e0190f81febea41916c587410ecdec276d0fe4f4c0c524828f8/tissuebox-18.12.1.tar.gz" } ], "18.12.10": [ { "comment_text": "", "digests": { "md5": "74f072dd20546502d65f038a1c349728", "sha256": "ee4630d393373bfa74ae3c9c38aaafc6308b2992dea811d44fa41cc3faa481e6" }, "downloads": -1, "filename": "tissuebox-18.12.10.tar.gz", "has_sig": false, "md5_digest": "74f072dd20546502d65f038a1c349728", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5889, "upload_time": "2018-12-22T06:51:35", "url": "https://files.pythonhosted.org/packages/37/93/8c7027ed58aa8d453cb29eb62d383551c49921add4f31a52ef6dada4f0f6/tissuebox-18.12.10.tar.gz" } ], "18.12.11": [ { "comment_text": "", "digests": { "md5": "330f79d65b10488a3938b13b82311d7e", "sha256": "a660757b996a187527d3e32a551448841f1632f5e1f11ce5ea0d07cf68be19be" }, "downloads": -1, "filename": "tissuebox-18.12.11.tar.gz", "has_sig": false, "md5_digest": "330f79d65b10488a3938b13b82311d7e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6684, "upload_time": "2018-12-22T06:54:49", "url": "https://files.pythonhosted.org/packages/2e/2a/c4a527decdcdcd9f85c7d7b178ca38933177ac2bc8717215b70c431a2a77/tissuebox-18.12.11.tar.gz" } ], "18.12.12": [ { "comment_text": "", "digests": { "md5": "8f94868c91ecb3ded79c294c235f659c", "sha256": "af025dc7318d38071ba72f8f2ae731522badbd4475c7419eeed5524ad625b994" }, "downloads": -1, "filename": "tissuebox-18.12.12.tar.gz", "has_sig": false, "md5_digest": "8f94868c91ecb3ded79c294c235f659c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5923, "upload_time": "2018-12-22T07:08:48", "url": "https://files.pythonhosted.org/packages/2c/23/0223fd7c8918398c6b962a451325ee5113188f8b676d4eaefc7c4ea77166/tissuebox-18.12.12.tar.gz" } ], "18.12.2": [ { "comment_text": "", "digests": { "md5": "101156cb735c240bf8543d5ceb69f483", "sha256": "bbb84ecf29bd31d109738fd5a212d18b4fbeb670a91ce90e6d34cf8b0d779f6f" }, "downloads": -1, "filename": "tissuebox-18.12.2.tar.gz", "has_sig": false, "md5_digest": "101156cb735c240bf8543d5ceb69f483", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2598, "upload_time": "2018-12-06T01:27:49", "url": "https://files.pythonhosted.org/packages/43/9c/dd026a5b6bbd18055e70d23680d3c70d2c8a644944c939172795c31690c7/tissuebox-18.12.2.tar.gz" } ], "18.12.3": [ { "comment_text": "", "digests": { "md5": "f1c674fad3b9f1f4d7e6c1d9705100ee", "sha256": "50d04cc15d50259e15d91919b7a6b3069be651a87cceb93790d28fdb4ffddfe0" }, "downloads": -1, "filename": "tissuebox-18.12.3.tar.gz", "has_sig": false, "md5_digest": "f1c674fad3b9f1f4d7e6c1d9705100ee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2362, "upload_time": "2018-12-06T23:22:20", "url": "https://files.pythonhosted.org/packages/c3/bb/d3320f733f97f17d0a66935fb6fbd7ef8520f8877907d1a35bbf7a38a102/tissuebox-18.12.3.tar.gz" } ], "18.12.4": [ { "comment_text": "", "digests": { "md5": "66241985bc693ebe4a69c84cf26427f9", "sha256": "424e960ec5dad7160e707b10592ec9ae8577f6ab150b70073644e5438ad910cf" }, "downloads": -1, "filename": "tissuebox-18.12.4.tar.gz", "has_sig": false, "md5_digest": "66241985bc693ebe4a69c84cf26427f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2809, "upload_time": "2018-12-06T23:32:30", "url": "https://files.pythonhosted.org/packages/1f/b9/a6b849d3fe5eba5233327b8e29887442e1ce6d31867ed12e45b67b54e15a/tissuebox-18.12.4.tar.gz" } ], "18.12.5": [ { "comment_text": "", "digests": { "md5": "850a05fa85b8bee2b31e73488581fc4e", "sha256": "dbd5784a48060734e9b342143860e6af50e07ad35318fc2c288dfb0c979562c9" }, "downloads": -1, "filename": "tissuebox-18.12.5.tar.gz", "has_sig": false, "md5_digest": "850a05fa85b8bee2b31e73488581fc4e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2804, "upload_time": "2018-12-07T02:08:38", "url": "https://files.pythonhosted.org/packages/45/03/dbbfafac4fb02f6cf6854b8825fd019141efdeb06ff35be9bcb516306f50/tissuebox-18.12.5.tar.gz" } ], "18.12.6": [ { "comment_text": "", "digests": { "md5": "97abd0a17ddb6bbea911bfdada289a6b", "sha256": "82eb4000ab3db1344002f506e1dcca283b75297b53db726ab72ed2f54667f8d8" }, "downloads": -1, "filename": "tissuebox-18.12.6.tar.gz", "has_sig": false, "md5_digest": "97abd0a17ddb6bbea911bfdada289a6b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2807, "upload_time": "2018-12-07T02:15:54", "url": "https://files.pythonhosted.org/packages/b3/0b/b9e0520e75d6413efbb8eacb0079483217df558d5ebf286a1e42d0cbfb0b/tissuebox-18.12.6.tar.gz" } ], "18.12.7": [ { "comment_text": "", "digests": { "md5": "fa5c146d81bc4169c49223ec5564c7be", "sha256": "24bb14268f2a7c7b051feb15018ace9e094975b244d1074eaa79c8cd5eeba550" }, "downloads": -1, "filename": "tissuebox-18.12.7.tar.gz", "has_sig": false, "md5_digest": "fa5c146d81bc4169c49223ec5564c7be", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3200, "upload_time": "2018-12-22T06:24:41", "url": "https://files.pythonhosted.org/packages/64/56/dab55065a01984a47c8a9794d8530f15bfa9ee687f1cbc98c2c1af42e2a9/tissuebox-18.12.7.tar.gz" } ], "18.12.8": [ { "comment_text": "", "digests": { "md5": "60161ecfa4d31d8308c600a72b78c86b", "sha256": "d4be1a59e943d1978ff332f19d3a9f8d6775d5b477c4f64cb81ef23726f61d41" }, "downloads": -1, "filename": "tissuebox-18.12.8.tar.gz", "has_sig": false, "md5_digest": "60161ecfa4d31d8308c600a72b78c86b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5790, "upload_time": "2018-12-22T06:34:48", "url": "https://files.pythonhosted.org/packages/a5/c0/56caba1f8665b136545f91f7dde9aeb5f25f6159e9075ef206f6268270a3/tissuebox-18.12.8.tar.gz" } ], "18.12.9": [ { "comment_text": "", "digests": { "md5": "b02fef5627fd5d5ade851c04d43e199a", "sha256": "2aa5537662f20a4f89494d9bcd7cf737560b6796df94ea904ff2d6302e63c5e5" }, "downloads": -1, "filename": "tissuebox-18.12.9.tar.gz", "has_sig": false, "md5_digest": "b02fef5627fd5d5ade851c04d43e199a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5887, "upload_time": "2018-12-22T06:37:19", "url": "https://files.pythonhosted.org/packages/af/bb/ef791ece48d9404681823cf99234fc111d05829764672d11e3cdbc1271e1/tissuebox-18.12.9.tar.gz" } ], "2019.01.09": [ { "comment_text": "", "digests": { "md5": "9c9cf441d41ed843c72e98f46eda6bb6", "sha256": "c7387e5c98b8d320053dcab56aef1b153ba59ecc05b4307d97c2caab567b7ef4" }, "downloads": -1, "filename": "tissuebox-2019.01.09.tar.gz", "has_sig": false, "md5_digest": "9c9cf441d41ed843c72e98f46eda6bb6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7885, "upload_time": "2019-01-09T06:17:05", "url": "https://files.pythonhosted.org/packages/0d/1a/99affae7e1eb234bfbbbe0a9450af9d1c646599842c23cd48d05d702a46a/tissuebox-2019.01.09.tar.gz" } ], "2019.01.13": [ { "comment_text": "", "digests": { "md5": "ce9221a732b99e2db3bdf36920f27ecc", "sha256": "aa24e9c1c62f38fd9d55f3b1fdaf53febe21ba3e10b3954cff2c1b03eb5d65f2" }, "downloads": -1, "filename": "tissuebox-2019.01.13.tar.gz", "has_sig": false, "md5_digest": "ce9221a732b99e2db3bdf36920f27ecc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7463, "upload_time": "2019-01-13T12:35:18", "url": "https://files.pythonhosted.org/packages/44/f6/8bea88e4b8a354af9eddc9dd4434dbb6a323fe27c94d008cc892172c7a90/tissuebox-2019.01.13.tar.gz" } ], "2019.01.14": [ { "comment_text": "", "digests": { "md5": "c8dd385555eccf29191e7a446fa4be09", "sha256": "619c0c9d4ddacdb861dd979ebfe3a5c8e5210c60e386fff1fca98be1d987b163" }, "downloads": -1, "filename": "tissuebox-2019.01.14.tar.gz", "has_sig": false, "md5_digest": "c8dd385555eccf29191e7a446fa4be09", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7463, "upload_time": "2019-01-13T23:59:26", "url": "https://files.pythonhosted.org/packages/7a/03/6bd99067cacb7b68065cd33673fa52ef780ee2ef611b881a55112afa1c3b/tissuebox-2019.01.14.tar.gz" } ], "2019.01.15": [ { "comment_text": "", "digests": { "md5": "803006f8b10f745a475d534a101d768b", "sha256": "51ada537f0821114cbb636a59ba29b8f0c06758cdbd1f74a791baf092ee42e21" }, "downloads": -1, "filename": "tissuebox-2019.01.15.tar.gz", "has_sig": false, "md5_digest": "803006f8b10f745a475d534a101d768b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7485, "upload_time": "2019-01-14T00:09:21", "url": "https://files.pythonhosted.org/packages/b3/c8/cb3ea50059ee3c079bb94ecdd33e594efd52234b3ed3a1d50ee768550733/tissuebox-2019.01.15.tar.gz" } ], "2019.01.16": [ { "comment_text": "", "digests": { "md5": "aba069e20680f7435e81b8e1293ae69f", "sha256": "fa2416d9a321e024d9fdc4558765fdfeb3034c7b6e62e0c07deb79c3bde9d767" }, "downloads": -1, "filename": "tissuebox-2019.01.16.tar.gz", "has_sig": false, "md5_digest": "aba069e20680f7435e81b8e1293ae69f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7485, "upload_time": "2019-01-14T00:30:09", "url": "https://files.pythonhosted.org/packages/0a/4d/7376d8993a783da3abcfd1fc2ca262e960b34d6eddd743377a9061ffd269/tissuebox-2019.01.16.tar.gz" } ], "2019.01.17": [ { "comment_text": "", "digests": { "md5": "2776272a736104edd86e891962e269a3", "sha256": "eb461ebc1a6e7ac744ac47cae962d7cab92588938bb1a866b127caaf97453352" }, "downloads": -1, "filename": "tissuebox-2019.01.17.tar.gz", "has_sig": false, "md5_digest": "2776272a736104edd86e891962e269a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8089, "upload_time": "2019-01-14T14:10:55", "url": "https://files.pythonhosted.org/packages/cb/7a/763a2c9f07424669b6da6c3ff65f74fca83e842f9227f644bc90799aefe1/tissuebox-2019.01.17.tar.gz" } ], "2019.01.18": [ { "comment_text": "", "digests": { "md5": "0c6516e0ea878fb39787ea84819265a0", "sha256": "4ff3991bd05d9630f34eb32368ca438a39ef671eb2c787399e1839d8ddbfff20" }, "downloads": -1, "filename": "tissuebox-2019.01.18.tar.gz", "has_sig": false, "md5_digest": "0c6516e0ea878fb39787ea84819265a0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8276, "upload_time": "2019-01-16T22:45:12", "url": "https://files.pythonhosted.org/packages/82/c9/5c420865c608cc7eb7a0c06d1a60c8273466d49fd248e6afce38e5887d3d/tissuebox-2019.01.18.tar.gz" } ], "2019.01.19": [ { "comment_text": "", "digests": { "md5": "66aace2bf48ea451f220a75d081f6779", "sha256": "3db4a22104e21c8500f5012611bc65b69fb6e24a1570d0713e93d3bbeab167e1" }, "downloads": -1, "filename": "tissuebox-2019.01.19.tar.gz", "has_sig": false, "md5_digest": "66aace2bf48ea451f220a75d081f6779", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8334, "upload_time": "2019-01-16T23:51:43", "url": "https://files.pythonhosted.org/packages/5c/ef/22764133dbaa48821370f4c575f6cd32ca98b63ee36c3ef36659d8fffd7e/tissuebox-2019.01.19.tar.gz" } ], "2019.01.20": [ { "comment_text": "", "digests": { "md5": "9d69e4cc82ff849c28148805a385f140", "sha256": "1267f141f22bc81fa11ff1633fe8e7edf9c7185ae3c6e2a857dd8f06c7c3775c" }, "downloads": -1, "filename": "tissuebox-2019.01.20.tar.gz", "has_sig": false, "md5_digest": "9d69e4cc82ff849c28148805a385f140", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8349, "upload_time": "2019-01-20T23:35:08", "url": "https://files.pythonhosted.org/packages/b9/fb/3c45192e720f9bd6a7d05c49ac180730fdc4fdbca366100d49c0119dfc9b/tissuebox-2019.01.20.tar.gz" } ], "2019.01.21": [ { "comment_text": "", "digests": { "md5": "0f73b504dbd707aef0e28016505d95d6", "sha256": "8bcf08850327ea5a7bece2bdd445c977e8d0290a0c7ca0bfba10e599fd0baca9" }, "downloads": -1, "filename": "tissuebox-2019.01.21.tar.gz", "has_sig": false, "md5_digest": "0f73b504dbd707aef0e28016505d95d6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8375, "upload_time": "2019-01-21T00:04:33", "url": "https://files.pythonhosted.org/packages/9b/d2/d6ede16d4a3df17f4483fdef32cba40c57f13c67b3adfa133d8bd0c9f220/tissuebox-2019.01.21.tar.gz" } ], "2019.01.22": [ { "comment_text": "", "digests": { "md5": "d19af2ee77bc70ca92522e69518ca1c2", "sha256": "a4e984f0cf625b9716c37625f426260917b5a4966393cfa1499f4c8edd88af40" }, "downloads": -1, "filename": "tissuebox-2019.01.22.tar.gz", "has_sig": false, "md5_digest": "d19af2ee77bc70ca92522e69518ca1c2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8392, "upload_time": "2019-01-22T00:35:44", "url": "https://files.pythonhosted.org/packages/94/30/3f585b00f97a3600a4dbb6bd51a8965ef19b701db060e2ece15eec3dab50/tissuebox-2019.01.22.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d19af2ee77bc70ca92522e69518ca1c2", "sha256": "a4e984f0cf625b9716c37625f426260917b5a4966393cfa1499f4c8edd88af40" }, "downloads": -1, "filename": "tissuebox-2019.01.22.tar.gz", "has_sig": false, "md5_digest": "d19af2ee77bc70ca92522e69518ca1c2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8392, "upload_time": "2019-01-22T00:35:44", "url": "https://files.pythonhosted.org/packages/94/30/3f585b00f97a3600a4dbb6bd51a8965ef19b701db060e2ece15eec3dab50/tissuebox-2019.01.22.tar.gz" } ] }