Package: recipie
RecipiePython idoms and recipesSubmoduleSome recipie modules having the same name with standard libraries are meant
as a drop in replacement for their counter parts. For example:# Replace contextlib by recipie.contextlib

#from contextlib import *
from recipie.contextlib import *

# All standard contextlib and recipie.contextlib extensions are availablecontextlibcleanup(func, *args, **kwargs) [0.0.3]Executes a clean up task on exiting context. The clean up task can be canceled.Example:with cleanup(undo, arg) as cleanup_task:
    result = action()
    if result:
        cleanup_task.cancel()commit(func, *args, **kwargs) [0.0.1]Executesfuncif the code ran to completion without any error:Example:def save_data(data):
    ...

with commit(save_data, data):
    # other actions
    ...

    # save_data is called if there is no errorAlso seerollbackrollback(func, *args, **kwargs) [0.0.1]Executesfuncif when encouter errorExample:def undo(data):
    ...

with rollback(undo, data):
    # Other actions
    ...Also see ***commitBuffer [0.0.2]Accumulates data into a buffer to be processed when the buffer is full.Example:def save_data(data: list[int]):
    ...

with Buffer(1000, save_data) as buffer:
    for i in range(1500):
        buffer.add(i)
        # On 1001th item, called save_data to save previous 1000 items
# When out of context, call save_data on the last 500 itemsfunctools@scoped [0.0.2]"Namespaces are one honking great idea -- let's do more of those!"Decorates a function to make it part of another namespaceExamples:def retry():
    ...

# Put no_delay under "retry" so it can only be refered to as retry.no_delay
@scoped(retry)
def no_delay():
    ...@default_on_error(value, errors) [0.0.1]Decorates a function to return the specifiedvalueiferrorsis raised.value: Default value to return on errorerrors: Error or tuple of errors to check forExample:@default_on_error(None, KeyError)
def get_from_dict(dict_, key):
    return dict_[key] # Possible KeyError

value = get_from_dict(d, "Test") # Value is None when "Test" is not in d@skip_on_error(errors) [0.0.1]Decorates a function to return None iferrorsis raised (equivalent to @default_on_error(None, errors)@retry(tries, errors, error_filter, delay_gen, log_error) [0.0.1]Retries functiontriestimes if encounter an error that matches errors and error_filtertries: Number of attempts on the function. Must be at least 2errors: exception or tuple of exception to retryerror_filter: function that takes in an error and returnsTrueif it is a retriable errordelay_gen: Delay generator that produce an iterator of delay values for
use between attempts.
Example:@retry(3, NetworkError) # Retry 3 times on NetworkError)
def get_db_connection():
   ...

conn = get_db_connection() # Automatically retry on network errorEithererrorsorerror_filtermust be specifiedPredefined delay policies:retry.no_delay: No delay between attempts. This is picked up when no delay policy specified.
It is equivalent toretry.const_delay(0).retry.const_delay(delay): Delay in seconds as specified bydelayretry.expo_backoff(base, cap, jitter): exponential backoff delay. With no jitter, values
aremax(base * 2 ^ n, cap).retry.no_jitter: (default) actual delay is fixed at the calculated valueretry.half_jitter: actual delay is randomly picked from [value/2, value)retry.full_jitter: actual delay is randomly picked from [0, value)