Metadata-Version: 2.0
Name: reloadable
Version: 0.1.4
Summary: Rerun a function upon failure
Home-page: https://bitbucket.org/sievetech/reloadable
Author: www.sieve.com.br
Author-email: ti@sieve.com.br
License: UNKNOWN
Description-Content-Type: UNKNOWN
Keywords: reloadable recover decorator loop cli sieve
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Topic :: Utilities
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4

Reloadable
==========

|Build Status| |codecov| |Python Versions| |pypi|

Reruns a function upon failure

Usage
-----
The function ``my_func`` will run indefinitely until it stops raising exceptions,
which will never happen in this case.

.. code-block:: python

    from reloadable import reloadable

    @reloadable()
    def my_func():
        raise Exception('Oops')

This module is useful when we want to run something forever, like a code
that connects to a queue en fetches messages. Eventually it may disconnect and
raise an error trying to fetch a message, so reloadable can retry connecting.

.. code-block:: python

    @reloadable()
    def get_message():
        conn = Queue(host='...', password='...')

        while True:
            message = conn.fetch_message()
            # probably process message afterwards...

You can config a callback function that receives an exception, which will be
called if it occurs.

.. code-block:: python

    def shit_happens(exception):
        logger.exception(exception)

    @reloadable(exception_callback=shit_happens)
    def dont_stop():
        raise Exception('Deal with it')

You can also wait some time before the next respawn

.. code-block:: python

    @reloadable(sleep_time=7)  # wait 7 seconds before running `get_message` after a failure 
    def get_message():
        # some code...

You can always stop reloadable with a ``KeyboardInterrupt`` exception
(usually triggered by ``^C``, but not necessarily).

Another option is to configure the stop condition exception.

.. code-block:: python

    @reloadable(stop_condition_exception=ValueError)
    def i_will_stop():
        raise ValueError('something went wrong')

Or you can define it globally, which will be used if local stop condition wasn't defined

.. code-block:: python

    from reloadable import reloadable, configure

    configure(stop_condition_exception=KeyError)

    @reloadable()
    def i_will_stop():
        raise KeyError('...')

You may also want to limit the number of times that the decorator should try
rerun the function

.. code-block:: python

    from reloadable import reloadable

    @reloadable(max_reloads=2)
    def a_func():
        raise KeyError('...')

Alternatively you can disable the reloadable decorator via configuration,
which is useful during unittests.

.. code-block:: python

    from reloadable import configure, reloadable

    configure(enabled=False)

    @reloadable()  # When disabled, it does nothing
    def i_am_free():
        return '\o/'

Tests
-----
``python -m unittest -v tests``

Installation
------------
``pip install reloadable``


.. |Build Status| image:: https://travis-ci.org/diogommartins/reloadable.svg?branch=master
   :target: https://travis-ci.org/diogommartins/reloadable

.. |codecov| image:: https://codecov.io/gh/diogommartins/reloadable/branch/master/graph/badge.svg
   :target: https://codecov.io/gh/diogommartins/reloadable

.. |pypi| image:: https://img.shields.io/pypi/v/reloadable.svg
   :target: https://pypi.python.org/pypi/reloadable

.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/reloadable.svg
   :target: https://pypi.python.org/pypi/reloadable


