{ "info": { "author": "Tomas Aparicio", "author_email": "tomas+python@aparicio.me", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: Jython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "riprova |Build Status| |PyPI| |Coverage Status| |Documentation Status| |Quality| |Versions|\n===========================================================================================\n\n``riprova`` (meaning ``retry`` in Italian) is a small, general-purpose and versatile `Python`_ library\nthat provides retry mechanisms with multiple backoff strategies for any sort of failed operations.\n\nIt's domain agnostic, highly customizable, extensible and provides a minimal API that's easy to instrument in any code base via decorators, context managers or raw API consumption.\n\nFor a brief introduction about backoff mechanisms for potential failed operations, `read this article`_.\n\n\nFeatures\n--------\n\n- Retry decorator for simple and idiomatic consumption.\n- Simple Pythonic programmatic interface.\n- Maximum retry timeout support.\n- Supports error `whitelisting`_ and `blacklisting`_.\n- Supports custom `error evaluation`_ retry logic (useful to retry only in specific cases).\n- Automatically retry operations on raised exceptions.\n- Supports `asynchronous coroutines`_ with both ``async/await`` and ``yield from`` syntax.\n- Configurable maximum number of retry attempts.\n- Highly configurable supporting max retries, timeouts or retry notifier callback.\n- Built-in backoff strategies: constant, `fibonacci`_ and `exponential`_ backoffs.\n- Supports sync/async context managers.\n- Pluggable custom backoff strategies.\n- Lightweight library with almost zero embedding cost.\n- Works with Python +2.6, 3.0+ and PyPy.\n\n\nBackoff strategies\n------------------\n\nList of built-in backoff strategies.\n\n- `Constant backoff`_\n- `Fibonacci backoff`_\n- `Exponential backoff`_\n\nYou can also implement your own one easily.\nSee `ConstantBackoff`_ for an implementation reference.\n\n\nInstallation\n------------\n\nUsing ``pip`` package manager (requires pip 1.9+. Upgrade it running: ``pip install -U pip``):\n\n.. code-block:: bash\n\n pip install -U riprova\n\nOr install the latest sources from Github:\n\n.. code-block:: bash\n\n pip install -e git+git://github.com/h2non/riprova.git#egg=riprova\n\n\nAPI\n---\n\n- riprova.retry_\n- riprova.Retrier_\n- riprova.AsyncRetrier_\n- riprova.Backoff_\n- riprova.ConstantBackoff_\n- riprova.FibonacciBackoff_\n- riprova.ExponentialBackoff_\n- riprova.ErrorWhitelist_\n- riprova.ErrorBlacklist_\n- riprova.add_whitelist_error_\n- riprova.RetryError_\n- riprova.RetryTimeoutError_\n- riprova.MaxRetriesExceeded_\n- riprova.NotRetriableError_\n\n\n.. _riprova.retry: http://riprova.readthedocs.io/en/latest/api.html#riprova.retry\n.. _riprova.Retrier: http://riprova.readthedocs.io/en/latest/api.html#riprova.Retrier\n.. _riprova.AsyncRetrier: http://riprova.readthedocs.io/en/latest/api.html#riprova.AsyncRetrier\n.. _riprova.Backoff: http://riprova.readthedocs.io/en/latest/api.html#riprova.Backoff\n.. _riprova.ConstantBackoff: http://riprova.readthedocs.io/en/latest/api.html#riprova.ConstantBackoff\n.. _riprova.FibonacciBackoff: http://riprova.readthedocs.io/en/latest/api.html#riprova.FibonacciBackoff\n.. _riprova.ExponentialBackoff: http://riprova.readthedocs.io/en/latest/api.html#riprova.ExponentialBackoff\n.. _riprova.ErrorWhitelist: http://riprova.readthedocs.io/en/latest/api.html#riprova.ErrorWhitelist\n.. _riprova.ErrorBlacklist: http://riprova.readthedocs.io/en/latest/api.html#riprova.ErrorBlacklist\n.. _riprova.add_whitelist_error: http://riprova.readthedocs.io/en/latest/api.html#riprova.add_whitelist_error\n.. _riprova.RetryError: http://riprova.readthedocs.io/en/latest/api.html#riprova.RetryError\n.. _riprova.RetryTimeoutError: http://riprova.readthedocs.io/en/latest/api.html#riprova.RetryTimeoutError\n.. _riprova.MaxRetriesExceeded: http://riprova.readthedocs.io/en/latest/api.html#riprova.MaxRetriesExceeded\n.. _riprova.NotRetriableError: http://riprova.readthedocs.io/en/latest/api.html#riprova.NotRetriableError\n\n\nExamples\n^^^^^^^^\n\nYou can see more featured examples from the `documentation` site.\n\n**Basic usage examples**:\n\n.. code-block:: python\n\n import riprova\n\n @riprova.retry\n def task():\n \"\"\"Retry operation if it fails with constant backoff (default)\"\"\"\n\n @riprova.retry(backoff=riprova.ConstantBackoff(retries=5))\n def task():\n \"\"\"Retry operation if it fails with custom max number of retry attempts\"\"\"\n\n @riprova.retry(backoff=riprova.ExponentialBackOff(factor=0.5))\n def task():\n \"\"\"Retry operation if it fails using exponential backoff\"\"\"\n\n @riprova.retry(timeout=10)\n def task():\n \"\"\"Raises a TimeoutError if the retry loop exceeds from 10 seconds\"\"\"\n\n def on_retry(err, next_try):\n print('Operation error: {}'.format(err))\n print('Next try in: {}ms'.format(next_try))\n\n @riprova.retry(on_retry=on_retry)\n def task():\n \"\"\"Subscribe via function callback to every retry attempt\"\"\"\n\n def evaluator(response):\n # Force retry operation if not a valid response\n if response.status >= 400:\n raise RuntimeError('invalid response status') # or simple return True\n # Otherwise return False, meaning no retry\n return False\n\n @riprova.retry(evaluator=evaluator)\n def task():\n \"\"\"Use a custom evaluator function to determine if the operation failed or not\"\"\"\n\n @riprova.retry\n async def task():\n \"\"\"Asynchronous coroutines are also supported :)\"\"\"\n\n\n**Retry failed HTTP requests**:\n\n.. code-block:: python\n\n import pook\n import requests\n from riprova import retry\n\n # Define HTTP mocks to simulate failed requests\n pook.get('server.com').times(3).reply(503)\n pook.get('server.com').times(1).reply(200).json({'hello': 'world'})\n\n\n # Retry evaluator function used to determine if the operated failed or not\n def evaluator(response):\n if response != 200:\n return Exception('failed request') # you can also simply return True\n return False\n\n\n # On retry even subscriptor\n def on_retry(err, next_try):\n print('Operation error {}'.format(err))\n print('Next try in {}ms'.format(next_try))\n\n\n # Register retriable operation\n @retry(evaluator=evaluator, on_retry=on_retry)\n def fetch(url):\n return requests.get(url)\n\n\n # Run task that might fail\n fetch('http://server.com')\n\n\n\nLicense\n-------\n\nMIT - Tomas Aparicio\n\n.. _exponential: https://en.wikipedia.org/wiki/Exponential_backoff\n.. _fibonacci: https://en.wikipedia.org/wiki/Fibonacci_number\n.. _asyncio: https://docs.python.org/3.5/library/asyncio.html\n.. _Python: http://python.org\n.. _annotated API reference: https://h2non.github.io/paco\n.. _async/await: https://www.python.org/dev/peps/pep-0492/\n.. _yield from: https://www.python.org/dev/peps/pep-0380/\n.. _documentation: http://riprova.readthedocs.io/en/latest/examples.html\n.. _read this article: http://dthain.blogspot.ie/2009/02/exponential-backoff-in-distributed.html\n.. _Constant backoff: http://riprova.readthedocs.io/en/latest/api.html#riprova.ConstantBackoff\n.. _Fibonacci backoff: http://riprova.readthedocs.io/en/latest/api.html#riprova.FibonacciBackoff\n.. _Exponential backoff: http://riprova.readthedocs.io/en/latest/api.html#riprova.ExponentialBackOff\n.. _ConstantBackoff: https://github.com/h2non/riprova/blob/master/riprova/strategies/constant.py\n.. _whitelisting: https://github.com/h2non/riprova/blob/master/examples/whitelisting_errors.py\n.. _blacklisting: https://github.com/h2non/riprova/blob/master/examples/blacklisting_errors.py\n.. _error evaluation: https://github.com/h2non/riprova/blob/master/examples/http_request.py\n.. _asynchronous coroutines: https://github.com/h2non/riprova/blob/master/examples/http_asyncio.py\n\n.. |Build Status| image:: https://travis-ci.org/h2non/riprova.svg?branch=master\n :target: https://travis-ci.org/h2non/riprova\n.. |PyPI| image:: https://img.shields.io/pypi/v/riprova.svg?maxAge=2592000?style=flat-square\n :target: https://pypi.python.org/pypi/riprova\n.. |Coverage Status| image:: https://coveralls.io/repos/github/h2non/riprova/badge.svg?branch=master\n :target: https://coveralls.io/github/h2non/riprova?branch=master\n.. |Documentation Status| image:: https://img.shields.io/badge/docs-latest-green.svg?style=flat\n :target: http://riprova.readthedocs.io/en/latest/?badge=latest\n.. |Quality| image:: https://codeclimate.com/github/h2non/riprova/badges/gpa.svg\n :target: https://codeclimate.com/github/h2non/riprova\n.. |Stability| image:: https://img.shields.io/pypi/status/riprova.svg\n :target: https://pypi.python.org/pypi/riprova\n.. |Versions| image:: https://img.shields.io/pypi/pyversions/riprova.svg\n :target: https://pypi.python.org/pypi/riprova\n\n\n\nv0.2.7 / 2018-08-24\n-------------------\n\n * Merge pull request #20 from ffix/forward-exception-instance\n * Correct linter warnings\n * Re-raise exception instance instead of new exception with no args\n * Merge pull request #19 from EdwardBetts/spelling\n * Correct spelling mistakes.\n * feat(setup): support Python 3.7\n * feat(History): add version changes\n\nv0.2.6 / 2018-04-14\n-------------------\n\n* fix(#17): handle as legit retriable error Timeout exceptions.\n\nv0.2.5 / 2018-03-21\n-------------------\n\n* Merge pull request #15 from jstasiak/allow-newer-six\n* Allow newer six\n* feat(History): update changes\n\nv0.2.5 / 2018-03-21\n------------------\n\n* Merge pull request #15 from jstasiak/allow-newer-six\n* Allow newer six\n* feat(History): update changes\n\nv0.2.4 / 2018-03-20\n-------------------\n\n* merge(#14): Allow subsecond maxtimes for ExponentialBackoff\n\nv0.2.3 / 2017-01-13\n-------------------\n\n* refactor(retry): remove unnecessary partial function\n* fix(retry): rename keyword param for partial application\n* feat(docs): improve description\n* refactor(Makefile): update publish task\n\nv0.2.2 / 2017-01-06\n-------------------\n\n* feat(package): add wheel distribution\n\nv0.2.1 / 2017-01-04\n-------------------\n\n* fix(retrier): remove debug print statement\n\nv0.2.0 / 2017-01-02\n-------------------\n\n* feat(core): use seconds as default time unit (introduces API breaking changes)\n* refactor(examples): update examples to use new time unit\n* feat(contextmanager): adds context manager support\n* feat(examples): add context manager example\n* feat: add context managers support\n\nv0.1.3 / 2016-12-30\n-------------------\n\n* refactor(async_retrier): simplify coroutine wrapper\n* feat(whitelist): add whitelist and blacklist support\n* feat(tests): add missing test cases for whitelist\n* feat(retry): pass error_evaluator param\n* fix(retrier): cast delay to float\n* fix(tests): use valid exception for Python 2.7\n* feat(#6): add custom error whilelist and custom error evaluator function\n* Merge pull request #8 from tsarpaul/master\n* refactor(decorator): do not expose retrier instance\n\nv0.1.2 / 2016-12-27\n-------------------\n\n* fix(decorator): wrap retries instance per function call\n\nv0.1.1 / 2016-12-27\n-------------------\n\n* fix(`#2`_): handle and forward ``asyncio.CancelledError`` as non-retriable error\n\nv0.1.0 / 2016-12-25\n-------------------\n\n* First version\n\n\n.. _#2: https://github.com/h2non/riprova/issues/2\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/h2non/riprova", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "riprova", "package_url": "https://pypi.org/project/riprova/", "platform": "", "project_url": "https://pypi.org/project/riprova/", "project_urls": { "Homepage": "https://github.com/h2non/riprova" }, "release_url": "https://pypi.org/project/riprova/0.2.7/", "requires_dist": null, "requires_python": "", "summary": "Small and versatile library to retry failed operations using different backoff strategies", "version": "0.2.7" }, "last_serial": 4204641, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "94a9744955e2a53b0932730c8552350d", "sha256": "9501f0897bdbae9b45e4f5fac46d82436217f92b0ef2e88a8f5ea591d2c8dc85" }, "downloads": -1, "filename": "riprova-0.1.0.tar.gz", "has_sig": false, "md5_digest": "94a9744955e2a53b0932730c8552350d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15336, "upload_time": "2016-12-25T22:50:29", "url": "https://files.pythonhosted.org/packages/bc/e0/165776d41aff2006b1b1838d2ac1158cee33a771159c3a9306c14c08c783/riprova-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "e98d269b9b2a869191c37af23f7eb012", "sha256": "50f8db7b70fc3aa9dac8eabeff7bbf91f96eda84c5c14927c036fffd7fdb32e7" }, "downloads": -1, "filename": "riprova-0.1.1.tar.gz", "has_sig": false, "md5_digest": "e98d269b9b2a869191c37af23f7eb012", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15846, "upload_time": "2016-12-27T21:03:42", "url": "https://files.pythonhosted.org/packages/c6/91/01e18c63bdec18cb73e8da052bcdeaf377e5f58430ad9e5f41ca2efa8003/riprova-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "82b62faad00c757c1449aa35b9cd5d86", "sha256": "a9608c306e3e028f681518188c701fc7f1e3f5b25058db39b3cd1dc723cc4673" }, "downloads": -1, "filename": "riprova-0.1.2.tar.gz", "has_sig": false, "md5_digest": "82b62faad00c757c1449aa35b9cd5d86", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15946, "upload_time": "2016-12-27T21:46:20", "url": "https://files.pythonhosted.org/packages/88/17/99f073103167a4e66061f4e6c3bd46b159128dca8028824336d0085d5bdc/riprova-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "9967ac1fe015e60ed48580ce6314c860", "sha256": "e9e94d7b54d52bbe958b238934c5061728fecfe9c323816cefc11576e0ccff5f" }, "downloads": -1, "filename": "riprova-0.1.3.tar.gz", "has_sig": false, "md5_digest": "9967ac1fe015e60ed48580ce6314c860", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18968, "upload_time": "2016-12-30T20:08:51", "url": "https://files.pythonhosted.org/packages/3d/b5/e222ebd709a78b2d50e68cdcac238099ea5a89ae2c48e789caaffa8db1c0/riprova-0.1.3.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "f6ab69fa03c011fa38d93794c2405479", "sha256": "a6b8aab9c8b4a841831dbaf85fd47c044ff99d04b4c4f2073401b5381fdf8bbc" }, "downloads": -1, "filename": "riprova-0.2.0.tar.gz", "has_sig": false, "md5_digest": "f6ab69fa03c011fa38d93794c2405479", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19430, "upload_time": "2017-01-03T15:03:31", "url": "https://files.pythonhosted.org/packages/83/d8/0a6b0b2ee471864d8b0cc2f165cdab384c79c2e61409ce02bbffbcc9e2cf/riprova-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "5f4400eaa14f640ebde0ea2c1f6ae043", "sha256": "adbc82f67663b2cc3a26d5ac7d74df7d4f4adafd81b1a22ab3f98b2613605ced" }, "downloads": -1, "filename": "riprova-0.2.1.tar.gz", "has_sig": false, "md5_digest": "5f4400eaa14f640ebde0ea2c1f6ae043", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19475, "upload_time": "2017-01-04T12:05:40", "url": "https://files.pythonhosted.org/packages/81/8f/be90a6d2a7659c097bad4705c48e2e2a489745478bf245e0138b8d3ee697/riprova-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "acbd0164dc43ae821e4237d53c328bca", "sha256": "536899b447658eddf59edf36927a2b9ac0c366dd89405ff31dd538296c4f7f49" }, "downloads": -1, "filename": "riprova-0.2.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "acbd0164dc43ae821e4237d53c328bca", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 24968, "upload_time": "2017-01-06T10:58:38", "url": "https://files.pythonhosted.org/packages/52/14/068b607ccf47c1c321d9a6a80e4aba4e3c0d51b0b431c088adebafb9af19/riprova-0.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3fde3fa3a4dd46c9f7c515f050faa52c", "sha256": "d18c26efcfbbc14c1fca83c51541fd954df581e343241e7e313c83783cf52910" }, "downloads": -1, "filename": "riprova-0.2.2.tar.gz", "has_sig": false, "md5_digest": "3fde3fa3a4dd46c9f7c515f050faa52c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19547, "upload_time": "2017-01-06T10:58:36", "url": "https://files.pythonhosted.org/packages/98/49/06975bbf71fe882ab445f531464f83625a2cdbc79a0b03e4cfb423635f81/riprova-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "1fd9c82fa9f2cef552b65ed88946831b", "sha256": "147109f58b5533796016b5d3dcac60689e1257a386ca19944602cd86d9bbb29d" }, "downloads": -1, "filename": "riprova-0.2.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1fd9c82fa9f2cef552b65ed88946831b", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 25262, "upload_time": "2017-01-13T09:29:41", "url": "https://files.pythonhosted.org/packages/71/56/70a9e9f6f30921d98f3c4e8bd4c3b37f69cdee02274c477656e14f13dcc4/riprova-0.2.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2cf79b5d9c8252989847ab3f7f235769", "sha256": "299742c3e61d2423823a415588f970301955ce7c57c82113455962c63cb03129" }, "downloads": -1, "filename": "riprova-0.2.3.tar.gz", "has_sig": false, "md5_digest": "2cf79b5d9c8252989847ab3f7f235769", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19797, "upload_time": "2017-01-13T09:29:38", "url": "https://files.pythonhosted.org/packages/d8/f9/b667903a72fa40e3eaf30a3db5a32e1b8a443a4e81ec65ce4c8c7056c20c/riprova-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "6797552a2b9dfae807de329edadc41be", "sha256": "47b052f5d413566255cf03bc1f82137700c361a568caa74d302d4e38769f40e3" }, "downloads": -1, "filename": "riprova-0.2.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6797552a2b9dfae807de329edadc41be", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 25316, "upload_time": "2018-03-20T02:42:05", "url": "https://files.pythonhosted.org/packages/ca/85/38de7bcd398adb5b767b18ffc51f2e07c6e58b78cb8f669f095906280bb9/riprova-0.2.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6ee0e1a4d01443b2aecf9704be521c81", "sha256": "06ea4d35b410c3087a3d30ccf56c1f6f7819a8645c9a7011c8ebf887444cfaf4" }, "downloads": -1, "filename": "riprova-0.2.4.tar.gz", "has_sig": false, "md5_digest": "6ee0e1a4d01443b2aecf9704be521c81", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19213, "upload_time": "2018-03-20T02:42:01", "url": "https://files.pythonhosted.org/packages/49/61/575c04d862929d324497048bd202347e758c4447492f0cdc6b0c00c9a0ff/riprova-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "2cd5439ceee765fb7ddbf05720de7313", "sha256": "8e71297b4a6858e2ea052909d18a7fb1ff0d279375c5e633e6fe803665e04a6b" }, "downloads": -1, "filename": "riprova-0.2.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2cd5439ceee765fb7ddbf05720de7313", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 25419, "upload_time": "2018-03-21T13:30:04", "url": "https://files.pythonhosted.org/packages/e5/ca/1397d6a0db148b803bcd41f585af7182c412a3deb8224a7ed95503f47836/riprova-0.2.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "833986a596123259b859cf31da07e673", "sha256": "cdfbf3db7e2cffa0ad66cd768ea63f0de94624bdd582081353adc9752a8c0ef4" }, "downloads": -1, "filename": "riprova-0.2.5.tar.gz", "has_sig": false, "md5_digest": "833986a596123259b859cf31da07e673", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19289, "upload_time": "2018-03-21T13:30:00", "url": "https://files.pythonhosted.org/packages/05/bc/e2f6b3f5a43bb68080c9c3d554ada6427ee29ea6ddc89507cfd25d466f7c/riprova-0.2.5.tar.gz" } ], "0.2.6": [ { "comment_text": "", "digests": { "md5": "f58252eadeaa4c99261ad7c6425eac87", "sha256": "24489c1a37293b6eb13d440ec45a7355eca6a3637b143906539420b09a22c5d3" }, "downloads": -1, "filename": "riprova-0.2.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f58252eadeaa4c99261ad7c6425eac87", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 25464, "upload_time": "2018-04-14T10:10:20", "url": "https://files.pythonhosted.org/packages/aa/98/e48cac925faa77a71a94352f99e687527160d1aa0eac243de5a3d6af09b6/riprova-0.2.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7423bfda6a3c24e69539bd5eda92406a", "sha256": "637662012853d558108298d7e6989bc65de28d378a80f4eadaa7542d647d66cb" }, "downloads": -1, "filename": "riprova-0.2.6.tar.gz", "has_sig": false, "md5_digest": "7423bfda6a3c24e69539bd5eda92406a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19354, "upload_time": "2018-04-14T10:10:16", "url": "https://files.pythonhosted.org/packages/0e/0a/f16dcf02e4c890d96c16538d8df6ec3c4ae46c90d34a003def2843601918/riprova-0.2.6.tar.gz" } ], "0.2.7": [ { "comment_text": "", "digests": { "md5": "16f8aa0c86add2b892dc430937c93105", "sha256": "b960451d48d3b6b5fc9909979d850ae172fc14037e9e13da0694ccc3e29c02ef" }, "downloads": -1, "filename": "riprova-0.2.7-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "16f8aa0c86add2b892dc430937c93105", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 25734, "upload_time": "2018-08-24T18:18:53", "url": "https://files.pythonhosted.org/packages/d6/12/e8864a85d8dfd11cfc4896f290f90e78c709741f75d4a5d1dc5ac79e697b/riprova-0.2.7-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7d762a0599827ea8b7f2366342842920", "sha256": "bf81471e51d92e3f7130839bea26ee5629f1aafa656db1350367c025e56eb911" }, "downloads": -1, "filename": "riprova-0.2.7.tar.gz", "has_sig": false, "md5_digest": "7d762a0599827ea8b7f2366342842920", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19534, "upload_time": "2018-08-24T18:18:50", "url": "https://files.pythonhosted.org/packages/4b/94/6591f1419f402b2f539d6bd5058f1d2b2576a7aaad97ebd5a984e9747c18/riprova-0.2.7.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "16f8aa0c86add2b892dc430937c93105", "sha256": "b960451d48d3b6b5fc9909979d850ae172fc14037e9e13da0694ccc3e29c02ef" }, "downloads": -1, "filename": "riprova-0.2.7-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "16f8aa0c86add2b892dc430937c93105", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 25734, "upload_time": "2018-08-24T18:18:53", "url": "https://files.pythonhosted.org/packages/d6/12/e8864a85d8dfd11cfc4896f290f90e78c709741f75d4a5d1dc5ac79e697b/riprova-0.2.7-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7d762a0599827ea8b7f2366342842920", "sha256": "bf81471e51d92e3f7130839bea26ee5629f1aafa656db1350367c025e56eb911" }, "downloads": -1, "filename": "riprova-0.2.7.tar.gz", "has_sig": false, "md5_digest": "7d762a0599827ea8b7f2366342842920", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19534, "upload_time": "2018-08-24T18:18:50", "url": "https://files.pythonhosted.org/packages/4b/94/6591f1419f402b2f539d6bd5058f1d2b2576a7aaad97ebd5a984e9747c18/riprova-0.2.7.tar.gz" } ] }